(** [infinite_from P l] means that we can find arbitrary long paths along which [P] does not hold above [l] *)
Definition infinite_from (P:list bool -> Prop) l := forall n, is_path_from P n l.
(** [has_infinite_path P] means that there is an infinite path (represented as a predicate) along which [P] does not hold at all *)
Definition has_infinite_path (P:list bool -> Prop) :=
exists (X:nat -> Prop), forall l, approx X l -> ~ P l.
(** [inductively_barred_at P n l] means that [P] eventually holds above [l] after at most [n] steps upwards *)
Inductive inductively_barred_at (P:list bool -> Prop) : nat -> list bool -> Prop :=
| now_at l n : P l -> inductively_barred_at P n l
| propagate_at l n :
inductively_barred_at P n (true::l) ->
inductively_barred_at P n (false::l) ->
inductively_barred_at P (S n) 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 exists n, inductively_barred_at P n (false::l) else infinite_from P (false::l)
end.

(* Specifications: *)
Lemma is_path_from_restrict : forall P n n' l, n <= n' ->
is_path_from P n' l -> is_path_from P n l.
Lemma inductively_barred_at_monotone : forall P l n n', n' <= n ->
inductively_barred_at P n' l -> inductively_barred_at P n l.