(** [inductively_barred P l] means that P eventually holds above l *)

Inductive inductively_barred P : list bool -> Prop :=
| now l : P l -> inductively_barred P l
| propagate l :
    inductively_barred P (true::l) ->
    inductively_barred P (false::l) ->
    inductively_barred P l.(** [inductively_barred P l] means that P eventually holds above l *)

Inductive inductively_barred P : list bool -> Prop :=
| now l : P l -> inductively_barred P l
| propagate l :
    inductively_barred P (true::l) ->
    inductively_barred P (false::l) ->
    inductively_barred P l.(** [inductively_barred P l] means that P eventually holds above l *)

Inductive inductively_barred P : list bool -> Prop :=
| now l : P l -> inductively_barred P l
| propagate l :
    inductively_barred P (true::l) ->
    inductively_barred P (false::l) ->
    inductively_barred P l.(** [approx X l] says that [l] is a boolean representation of a prefix of [X] *)

Fixpoint approx X (l:list bool) :=
  match l with
  | [] => True
  | b::l => approx X l /\ (if b then X (length l) else ~ X (length l))
  end.(** [barred P] means that for any infinite path represented as a predicate,
    the property [P] holds for some prefix of the path *)

Definition barred P :=
  forall (X:nat -> Prop), exists l, approx X l /\ P l.(** The proof proceeds by building a set [Y] of finite paths
   approximating either the smallest unbarred infinite path in [P], if
   there is one (taking [true]>[false]), or the path [true::true::...]
   if [P] happens to be inductively_barred *)

Fixpoint Y P (l:list bool) :=
  match l with
  | [] => True
  | b::l =>
      Y P l /\
      if b then inductively_barred P (false::l) else ~ inductively_barred P (false::l)
  end.

(* Specifications: *)
Lemma Y_unique : forall P l1 l2, length l1 = length l2 -> Y P l1 -> Y P l2 -> l1 = l2.