Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
A constructive proof of a version of Weak König's Lemma over a
decidable predicate in the formulation of which infinite paths are
treated as predicates. The representation of paths as relations
avoid the need for classical logic and unique choice. The
decidability condition is sufficient to ensure that some required
instance of double negation for disjunction of finite paths holds.
The idea of the proof comes from the proof of the weak König's
lemma from separation in second-order arithmetic.
Notice that we do not start from a tree but just from an arbitrary
predicate. Original Weak Konig's Lemma is the instantiation of
the lemma to a tree
Require Import WeakFan List. Import ListNotations. Require Import Omega.
is_path_from P n l means that there exists a path of length n
from l on which P does not hold
Inductive is_path_from (P:list bool -> Prop) : nat -> list bool -> Prop :=
| here l : ~ P l -> is_path_from P 0 l
| next_left l n : ~ P l -> is_path_from P n (true::l) -> is_path_from P (S n) l
| next_right l n : ~ P l -> is_path_from P n (false::l) -> is_path_from P (S n) l.
We give the characterization of is_path_from in terms of a more common arithmetical formula
P:list bool -> Propn:natl:list boolis_path_from P n l <-> (exists l' : list bool, length l' = n /\ (forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ l)))P:list bool -> Propn:natl:list boolis_path_from P n l <-> (exists l' : list bool, length l' = n /\ (forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ l)))P:list bool -> Propn:natl:list boolis_path_from P n l <-> (exists l' : list bool, length l' = n /\ (forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ l)))P:list bool -> Propn:natl:list boolis_path_from P n l -> exists l' : list bool, length l' = n /\ (forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ l))P:list bool -> Propn:natl:list bool(exists l' : list bool, length l' = n /\ (forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ l))) -> is_path_from P n lP:list bool -> Propn:natl:list boolis_path_from P n l -> exists l' : list bool, length l' = n /\ (forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ l))P:list bool -> Propl:list boolH:~ P lexists l' : list bool, length l' = 0 /\ (forall n' : nat, n' <= 0 -> ~ P (rev (firstn n' l') ++ l))P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)exists l'0 : list bool, length l'0 = S n /\ (forall n' : nat, n' <= S n -> ~ P (rev (firstn n' l'0) ++ l))P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)exists l'0 : list bool, length l'0 = S n /\ (forall n' : nat, n' <= S n -> ~ P (rev (firstn n' l'0) ++ l))P:list bool -> Propl:list boolH:~ P lexists l' : list bool, length l' = 0 /\ (forall n' : nat, n' <= 0 -> ~ P (rev (firstn n' l') ++ l))P:list bool -> Propl:list boolH:~ P llength [] = 0 /\ (forall n' : nat, n' <= 0 -> ~ P (rev (firstn n' []) ++ l))P:list bool -> Propl:list boolH:~ P llength [] = 0P:list bool -> Propl:list boolH:~ P lforall n' : nat, n' <= 0 -> ~ P (rev (firstn n' []) ++ l)P:list bool -> Propl:list boolH:~ P lforall n' : nat, n' <= 0 -> ~ P (rev (firstn n' []) ++ l)assumption.P:list bool -> Propl:list boolH:~ P l~ P (rev (firstn 0 []) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)exists l'0 : list bool, length l'0 = S n /\ (forall n' : nat, n' <= S n -> ~ P (rev (firstn n' l'0) ++ l))P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)length (true :: l') = S n /\ (forall n' : nat, n' <= S n -> ~ P (rev (firstn n' (true :: l')) ++ l))P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)length (true :: l') = S nP:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)forall n' : nat, n' <= S n -> ~ P (rev (firstn n' (true :: l')) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)forall n' : nat, n' <= S n -> ~ P (rev (firstn n' (true :: l')) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)H:0 <= S n~ P (rev (firstn 0 (true :: l')) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)n0:natH:S n0 <= S n~ P (rev (firstn (S n0) (true :: l')) ++ l)assumption.P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)H:0 <= S n~ P (rev (firstn 0 (true :: l')) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)n0:natH:S n0 <= S n~ P (rev (firstn (S n0) (true :: l')) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)n0:natH:S n0 <= S n~ P ((rev (firstn n0 l') ++ [true]) ++ l)apply HPl', le_S_n, H.P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ true :: l)n0:natH:S n0 <= S n~ P (rev (firstn n0 l') ++ [true] ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)exists l'0 : list bool, length l'0 = S n /\ (forall n' : nat, n' <= S n -> ~ P (rev (firstn n' l'0) ++ l))P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)length (false :: l') = S n /\ (forall n' : nat, n' <= S n -> ~ P (rev (firstn n' (false :: l')) ++ l))P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)length (false :: l') = S nP:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)forall n' : nat, n' <= S n -> ~ P (rev (firstn n' (false :: l')) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)forall n' : nat, n' <= S n -> ~ P (rev (firstn n' (false :: l')) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)H:0 <= S n~ P (rev (firstn 0 (false :: l')) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)n0:natH:S n0 <= S n~ P (rev (firstn (S n0) (false :: l')) ++ l)assumption.P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)H:0 <= S n~ P (rev (firstn 0 (false :: l')) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)n0:natH:S n0 <= S n~ P (rev (firstn (S n0) (false :: l')) ++ l)P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)n0:natH:S n0 <= S n~ P ((rev (firstn n0 l') ++ [false]) ++ l)apply HPl', le_S_n, H.P:list bool -> Propl:list booln:natHP:~ P ll':list boolHl':length l' = nHPl':forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ false :: l)n0:natH:S n0 <= S n~ P (rev (firstn n0 l') ++ [false] ++ l)P:list bool -> Propn:natl:list bool(exists l' : list bool, length l' = n /\ (forall n' : nat, n' <= n -> ~ P (rev (firstn n' l') ++ l))) -> is_path_from P n lP:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l)is_path_from P (length l') lP:list bool -> Propl:list boolHPl':forall n' : nat, n' <= length [] -> ~ P (rev (firstn n' []) ++ l)is_path_from P (length []) lP:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (true :: l') -> ~ P (rev (firstn n' (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0is_path_from P (length (true :: l')) lP:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (false :: l') -> ~ P (rev (firstn n' (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0is_path_from P (length (false :: l')) lP:list bool -> Propl:list boolHPl':forall n' : nat, n' <= length [] -> ~ P (rev (firstn n' []) ++ l)is_path_from P (length []) lP:list bool -> Propl:list boolHPl':forall n' : nat, n' <= length [] -> ~ P (rev (firstn n' []) ++ l)~ P lapply le_0_n.P:list bool -> Propl:list boolHPl':forall n' : nat, n' <= length [] -> ~ P (rev (firstn n' []) ++ l)0 <= length []P:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (true :: l') -> ~ P (rev (firstn n' (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0is_path_from P (length (true :: l')) lP:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (true :: l') -> ~ P (rev (firstn n' (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0~ P lP:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (true :: l') -> ~ P (rev (firstn n' (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0is_path_from P ((fix length (l0 : list bool) : nat := match l0 with | [] => 0 | _ :: l'0 => S (length l'0) end) l') (true :: l)apply (HPl' 0), le_0_n.P:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (true :: l') -> ~ P (rev (firstn n' (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0~ P lP:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (true :: l') -> ~ P (rev (firstn n' (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0is_path_from P ((fix length (l0 : list bool) : nat := match l0 with | [] => 0 | _ :: l'0 => S (length l'0) end) l') (true :: l)P:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (true :: l') -> ~ P (rev (firstn n' (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0is_path_from P (length l') (true :: l)P:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (true :: l') -> ~ P (rev (firstn n' (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ true :: l)P:list bool -> Propl, l':list boolHPl':forall n'0 : nat, n'0 <= length (true :: l') -> ~ P (rev (firstn n'0 (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n'0 : nat, n'0 <= length l' -> ~ P (rev (firstn n'0 l') ++ l0)) -> is_path_from P (length l') l0n':natH:S n' <= S (length l')~ P (rev (firstn n' l') ++ true :: l)P:list bool -> Propl, l':list boolHPl':forall n'0 : nat, n'0 <= length (true :: l') -> ~ P (rev (firstn n'0 (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n'0 : nat, n'0 <= length l' -> ~ P (rev (firstn n'0 l') ++ l0)) -> is_path_from P (length l') l0n':natH:~ P (rev (firstn (S n') (true :: l')) ++ l)~ P (rev (firstn n' l') ++ true :: l)P:list bool -> Propl, l':list boolHPl':forall n'0 : nat, n'0 <= length (true :: l') -> ~ P (rev (firstn n'0 (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n'0 : nat, n'0 <= length l' -> ~ P (rev (firstn n'0 l') ++ l0)) -> is_path_from P (length l') l0n':natH:~ P ((rev (firstn n' l') ++ [true]) ++ l)~ P (rev (firstn n' l') ++ true :: l)assumption.P:list bool -> Propl, l':list boolHPl':forall n'0 : nat, n'0 <= length (true :: l') -> ~ P (rev (firstn n'0 (true :: l')) ++ l)IHl':forall l0 : list bool, (forall n'0 : nat, n'0 <= length l' -> ~ P (rev (firstn n'0 l') ++ l0)) -> is_path_from P (length l') l0n':natH:~ P (rev (firstn n' l') ++ [true] ++ l)~ P (rev (firstn n' l') ++ true :: l)P:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (false :: l') -> ~ P (rev (firstn n' (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0is_path_from P (length (false :: l')) lP:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (false :: l') -> ~ P (rev (firstn n' (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0~ P lP:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (false :: l') -> ~ P (rev (firstn n' (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0is_path_from P ((fix length (l0 : list bool) : nat := match l0 with | [] => 0 | _ :: l'0 => S (length l'0) end) l') (false :: l)apply (HPl' 0), le_0_n.P:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (false :: l') -> ~ P (rev (firstn n' (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0~ P lP:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (false :: l') -> ~ P (rev (firstn n' (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0is_path_from P ((fix length (l0 : list bool) : nat := match l0 with | [] => 0 | _ :: l'0 => S (length l'0) end) l') (false :: l)P:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (false :: l') -> ~ P (rev (firstn n' (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0is_path_from P (length l') (false :: l)P:list bool -> Propl, l':list boolHPl':forall n' : nat, n' <= length (false :: l') -> ~ P (rev (firstn n' (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ l0)) -> is_path_from P (length l') l0forall n' : nat, n' <= length l' -> ~ P (rev (firstn n' l') ++ false :: l)P:list bool -> Propl, l':list boolHPl':forall n'0 : nat, n'0 <= length (false :: l') -> ~ P (rev (firstn n'0 (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n'0 : nat, n'0 <= length l' -> ~ P (rev (firstn n'0 l') ++ l0)) -> is_path_from P (length l') l0n':natH:S n' <= S (length l')~ P (rev (firstn n' l') ++ false :: l)P:list bool -> Propl, l':list boolHPl':forall n'0 : nat, n'0 <= length (false :: l') -> ~ P (rev (firstn n'0 (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n'0 : nat, n'0 <= length l' -> ~ P (rev (firstn n'0 l') ++ l0)) -> is_path_from P (length l') l0n':natH:~ P (rev (firstn (S n') (false :: l')) ++ l)~ P (rev (firstn n' l') ++ false :: l)P:list bool -> Propl, l':list boolHPl':forall n'0 : nat, n'0 <= length (false :: l') -> ~ P (rev (firstn n'0 (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n'0 : nat, n'0 <= length l' -> ~ P (rev (firstn n'0 l') ++ l0)) -> is_path_from P (length l') l0n':natH:~ P ((rev (firstn n' l') ++ [false]) ++ l)~ P (rev (firstn n' l') ++ false :: l)assumption. Qed.P:list bool -> Propl, l':list boolHPl':forall n'0 : nat, n'0 <= length (false :: l') -> ~ P (rev (firstn n'0 (false :: l')) ++ l)IHl':forall l0 : list bool, (forall n'0 : nat, n'0 <= length l' -> ~ P (rev (firstn n'0 l') ++ l0)) -> is_path_from P (length l') l0n':natH:~ P (rev (firstn n' l') ++ [false] ++ l)~ P (rev (firstn n' l') ++ false :: l)
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. Require Import Compare_dec Le Lt.forall (P : list bool -> Prop) (n n' : nat) (l : list bool), n <= n' -> is_path_from P n' l -> is_path_from P n lforall (P : list bool -> Prop) (n n' : nat) (l : list bool), n <= n' -> is_path_from P n' l -> is_path_from P n lP:list bool -> Propn:natHle:n <= 0l:list boolH:~ P lis_path_from P n lP:list bool -> Propn, n0:natHle:n <= S n0l:list boolH:~ P lH0:is_path_from P n0 (true :: l)IHis_path_from:forall n1 : nat, n1 <= n0 -> is_path_from P n1 (true :: l)is_path_from P n lP:list bool -> Propn, n0:natHle:n <= S n0l:list boolH:~ P lH0:is_path_from P n0 (false :: l)IHis_path_from:forall n1 : nat, n1 <= n0 -> is_path_from P n1 (false :: l)is_path_from P n lP:list bool -> Propn:natHle:n <= 0l:list boolH:~ P lis_path_from P n lP:list bool -> Propl:list boolH:~ P lis_path_from P 0 lassumption.P:list bool -> Propl:list boolH:~ P l~ P lP:list bool -> Propn, n0:natHle:n <= S n0l:list boolH:~ P lH0:is_path_from P n0 (true :: l)IHis_path_from:forall n1 : nat, n1 <= n0 -> is_path_from P n1 (true :: l)is_path_from P n lP:list bool -> Propn0:natHle:0 <= S n0l:list boolH:~ P lH0:is_path_from P n0 (true :: l)IHis_path_from:forall n : nat, n <= n0 -> is_path_from P n (true :: l)is_path_from P 0 lP:list bool -> Propn, n0:natHle:S n <= S n0l:list boolH:~ P lH0:is_path_from P n0 (true :: l)IHis_path_from:forall n1 : nat, n1 <= n0 -> is_path_from P n1 (true :: l)is_path_from P (S n) lP:list bool -> Propn0:natHle:0 <= S n0l:list boolH:~ P lH0:is_path_from P n0 (true :: l)IHis_path_from:forall n : nat, n <= n0 -> is_path_from P n (true :: l)is_path_from P 0 lassumption.P:list bool -> Propn0:natHle:0 <= S n0l:list boolH:~ P lH0:is_path_from P n0 (true :: l)IHis_path_from:forall n : nat, n <= n0 -> is_path_from P n (true :: l)~ P lapply next_left; auto using le_S_n.P:list bool -> Propn, n0:natHle:S n <= S n0l:list boolH:~ P lH0:is_path_from P n0 (true :: l)IHis_path_from:forall n1 : nat, n1 <= n0 -> is_path_from P n1 (true :: l)is_path_from P (S n) lP:list bool -> Propn, n0:natHle:n <= S n0l:list boolH:~ P lH0:is_path_from P n0 (false :: l)IHis_path_from:forall n1 : nat, n1 <= n0 -> is_path_from P n1 (false :: l)is_path_from P n lP:list bool -> Propn0:natHle:0 <= S n0l:list boolH:~ P lH0:is_path_from P n0 (false :: l)IHis_path_from:forall n : nat, n <= n0 -> is_path_from P n (false :: l)is_path_from P 0 lP:list bool -> Propn, n0:natHle:S n <= S n0l:list boolH:~ P lH0:is_path_from P n0 (false :: l)IHis_path_from:forall n1 : nat, n1 <= n0 -> is_path_from P n1 (false :: l)is_path_from P (S n) lP:list bool -> Propn0:natHle:0 <= S n0l:list boolH:~ P lH0:is_path_from P n0 (false :: l)IHis_path_from:forall n : nat, n <= n0 -> is_path_from P n (false :: l)is_path_from P 0 lassumption.P:list bool -> Propn0:natHle:0 <= S n0l:list boolH:~ P lH0:is_path_from P n0 (false :: l)IHis_path_from:forall n : nat, n <= n0 -> is_path_from P n (false :: l)~ P lapply next_right; auto using le_S_n. Qed.P:list bool -> Propn, n0:natHle:S n <= S n0l:list boolH:~ P lH0:is_path_from P n0 (false :: l)IHis_path_from:forall n1 : nat, n1 <= n0 -> is_path_from P n1 (false :: l)is_path_from P (S n) lforall (P : list bool -> Prop) (l : list bool) (n n' : nat), n' <= n -> inductively_barred_at P n' l -> inductively_barred_at P n lforall (P : list bool -> Prop) (l : list bool) (n n' : nat), n' <= n -> inductively_barred_at P n' l -> inductively_barred_at P n lP:list bool -> Propl:list booln, n':natHle:n' <= nHbar:inductively_barred_at P n' linductively_barred_at P n lP:list bool -> Propn, n0:natHle:n0 <= nl:list boolH:P linductively_barred_at P n lP:list bool -> Propn, n0:natHle:S n0 <= nl:list boolHbar1:inductively_barred_at P n0 (true :: l)Hbar2:inductively_barred_at P n0 (false :: l)IHHbar1:forall n1 : nat, n0 <= n1 -> inductively_barred_at P n1 (true :: l)IHHbar2:forall n1 : nat, n0 <= n1 -> inductively_barred_at P n1 (false :: l)inductively_barred_at P n lapply now_at; auto.P:list bool -> Propn, n0:natHle:n0 <= nl:list boolH:P linductively_barred_at P n lP:list bool -> Propn, n0:natHle:S n0 <= nl:list boolHbar1:inductively_barred_at P n0 (true :: l)Hbar2:inductively_barred_at P n0 (false :: l)IHHbar1:forall n1 : nat, n0 <= n1 -> inductively_barred_at P n1 (true :: l)IHHbar2:forall n1 : nat, n0 <= n1 -> inductively_barred_at P n1 (false :: l)inductively_barred_at P n lP:list bool -> Propn, n0:natHle:S n0 <= S nl:list boolHbar1:inductively_barred_at P n0 (true :: l)Hbar2:inductively_barred_at P n0 (false :: l)IHHbar1:forall n1 : nat, n0 <= n1 -> inductively_barred_at P n1 (true :: l)IHHbar2:forall n1 : nat, n0 <= n1 -> inductively_barred_at P n1 (false :: l)inductively_barred_at P (S n) lapply propagate_at; auto. Qed. Definition demorgan_or (P:list bool -> Prop) l l' := ~ (P l /\ P l') -> ~ P l \/ ~ P l'. Definition demorgan_inductively_barred_at P := forall n l, demorgan_or (inductively_barred_at P n) (true::l) (false::l).P:list bool -> Propn, n0:natHle:n0 <= nl:list boolHbar1:inductively_barred_at P n0 (true :: l)Hbar2:inductively_barred_at P n0 (false :: l)IHHbar1:forall n1 : nat, n0 <= n1 -> inductively_barred_at P n1 (true :: l)IHHbar2:forall n1 : nat, n0 <= n1 -> inductively_barred_at P n1 (false :: l)inductively_barred_at P (S n) lforall P : list bool -> Prop, demorgan_inductively_barred_at P -> forall (n : nat) (l : list bool), ~ inductively_barred_at P n l -> is_path_from P n lforall P : list bool -> Prop, demorgan_inductively_barred_at P -> forall (n : nat) (l : list bool), ~ inductively_barred_at P n l -> is_path_from P n lP:list bool -> PropHdemorgan:demorgan_inductively_barred_at Pl:list boolH:~ inductively_barred_at P 0 lis_path_from P 0 lP:list bool -> PropHdemorgan:demorgan_inductively_barred_at Pn:natIHn:forall l0 : list bool, ~ inductively_barred_at P n l0 -> is_path_from P n l0l:list boolH:~ inductively_barred_at P (S n) lis_path_from P (S n) lP:list bool -> PropHdemorgan:demorgan_inductively_barred_at Pl:list boolH:~ inductively_barred_at P 0 lis_path_from P 0 lP:list bool -> PropHdemorgan:demorgan_inductively_barred_at Pl:list boolH:~ inductively_barred_at P 0 l~ P lP:list bool -> PropHdemorgan:demorgan_inductively_barred_at Pl:list boolH:~ inductively_barred_at P 0 lH0:P lFalseP:list bool -> PropHdemorgan:demorgan_inductively_barred_at Pl:list boolH:~ inductively_barred_at P 0 lH0:P linductively_barred_at P 0 lauto.P:list bool -> PropHdemorgan:demorgan_inductively_barred_at Pl:list boolH:~ inductively_barred_at P 0 lH0:P lP lP:list bool -> PropHdemorgan:demorgan_inductively_barred_at Pn:natIHn:forall l0 : list bool, ~ inductively_barred_at P n l0 -> is_path_from P n l0l:list boolH:~ inductively_barred_at P (S n) lis_path_from P (S n) lP:list bool -> PropHdemorgan:demorgan_inductively_barred_at Pn:natIHn:forall l0 : list bool, ~ inductively_barred_at P n l0 -> is_path_from P n l0l:list boolH:~ inductively_barred_at P (S n) lH0:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))is_path_from P (S n) lapply Hdemorgan in H0 as [H0|H0]; apply IHn in H0; auto using is_path_from. Qed.P:list bool -> PropHdemorgan:demorgan_inductively_barred_at Pn:natIHn:forall l0 : list bool, ~ inductively_barred_at P n l0 -> is_path_from P n l0l:list boolH:~ inductively_barred_at P (S n) lH0:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))HnP:~ P lis_path_from P (S n) lforall (P : list bool -> Prop) (n : nat) (l : list bool), is_path_from P n l -> inductively_barred_at P n l -> Falseforall (P : list bool -> Prop) (n : nat) (l : list bool), is_path_from P n l -> inductively_barred_at P n l -> FalseP:list bool -> Propl:list boolH1:is_path_from P 0 lH2:inductively_barred_at P 0 lFalseP:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH1:is_path_from P (S n) lH2:inductively_barred_at P (S n) lFalseP:list bool -> Propl:list boolH1:is_path_from P 0 lH2:inductively_barred_at P 0 lFalseP:list bool -> Propl:list boolH2:inductively_barred_at P 0 lH:~ P lFalseauto.P:list bool -> Propl:list boolH:~ P lH0:P lFalseP:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH1:is_path_from P (S n) lH2:inductively_barred_at P (S n) lFalseP:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH2:inductively_barred_at P (S n) lH:~ P lH0:is_path_from P n (true :: l)FalseP:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH2:inductively_barred_at P (S n) lH:~ P lH0:is_path_from P n (false :: l)FalseP:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH2:inductively_barred_at P (S n) lH:~ P lH0:is_path_from P n (true :: l)FalseP:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH:~ P lH0:is_path_from P n (true :: l)H1:P lFalseP:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH:~ P lH0:is_path_from P n (true :: l)H1:inductively_barred_at P n (true :: l)H3:inductively_barred_at P n (false :: l)Falseauto.P:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH:~ P lH0:is_path_from P n (true :: l)H1:P lFalseapply IHn with (true::l); auto.P:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH:~ P lH0:is_path_from P n (true :: l)H1:inductively_barred_at P n (true :: l)H3:inductively_barred_at P n (false :: l)FalseP:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH2:inductively_barred_at P (S n) lH:~ P lH0:is_path_from P n (false :: l)FalseP:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH:~ P lH0:is_path_from P n (false :: l)H1:P lFalseP:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH:~ P lH0:is_path_from P n (false :: l)H1:inductively_barred_at P n (true :: l)H3:inductively_barred_at P n (false :: l)Falseauto.P:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH:~ P lH0:is_path_from P n (false :: l)H1:P lFalseapply IHn with (false::l); auto. Qed.P:list bool -> Propn:natIHn:forall l0 : list bool, is_path_from P n l0 -> inductively_barred_at P n l0 -> Falsel:list boolH:~ P lH0:is_path_from P n (false :: l)H1:inductively_barred_at P n (true :: l)H3:inductively_barred_at P n (false :: l)Falseforall (P : list bool -> Prop) (l : list bool) (n : nat), is_path_from P (S n) l -> inductively_barred_at P n (false :: l) -> is_path_from P n (true :: l)forall (P : list bool -> Prop) (l : list bool) (n : nat), is_path_from P (S n) l -> inductively_barred_at P n (false :: l) -> is_path_from P n (true :: l)P:list bool -> Propl:list booln:natH:is_path_from P (S n) lH1:~ P lH2:is_path_from P n (true :: l)H0:inductively_barred_at P n (false :: l)is_path_from P n (true :: l)P:list bool -> Propl:list booln:natH:is_path_from P (S n) lH1:~ P lH2:is_path_from P n (false :: l)H0:inductively_barred_at P n (false :: l)is_path_from P n (true :: l)auto.P:list bool -> Propl:list booln:natH:is_path_from P (S n) lH1:~ P lH2:is_path_from P n (true :: l)H0:inductively_barred_at P n (false :: l)is_path_from P n (true :: l)P:list bool -> Propl:list booln:natH:is_path_from P (S n) lH1:~ P lH2:is_path_from P n (false :: l)H0:inductively_barred_at P n (false :: l)is_path_from P n (true :: l)eauto using is_path_from_imp_inductively_barred_at. Qed.P:list bool -> Propl:list booln:natH:is_path_from P (S n) lH1:~ P lH2:is_path_from P n (false :: l)H0:inductively_barred_at P n (false :: l)Falseforall P : list bool -> Prop, demorgan_inductively_barred_at P -> forall l1 l2 : list bool, length l1 = length l2 -> Y P l1 -> Y P l2 -> l1 = l2forall P : list bool -> Prop, demorgan_inductively_barred_at P -> forall l1 l2 : list bool, length l1 = length l2 -> Y P l1 -> Y P l2 -> l1 = l2P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pforall l1 l2 : list bool, length l1 = length l2 -> Y P l1 -> Y P l2 -> l1 = l2P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Plength [] = length [] -> Y P [] -> Y P [] -> [] = []P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pb:booll2:list boollength [] = length (b :: l2) -> Y P [] -> Y P (b :: l2) -> [] = b :: l2P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll1:list boolIHl1:forall l2 : list bool, length l1 = length l2 -> Y P l1 -> Y P l2 -> l1 = l2length (a :: l1) = length [] -> Y P (a :: l1) -> Y P [] -> a :: l1 = []P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll1:list boolIHl1:forall l0 : list bool, length l1 = length l0 -> Y P l1 -> Y P l0 -> l1 = l0b:booll2:list boollength (a :: l1) = length (b :: l2) -> Y P (a :: l1) -> Y P (b :: l2) -> a :: l1 = b :: l2trivial.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Plength [] = length [] -> Y P [] -> Y P [] -> [] = []discriminate.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pb:booll2:list boollength [] = length (b :: l2) -> Y P [] -> Y P (b :: l2) -> [] = b :: l2discriminate.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll1:list boolIHl1:forall l2 : list bool, length l1 = length l2 -> Y P l1 -> Y P l2 -> l1 = l2length (a :: l1) = length [] -> Y P (a :: l1) -> Y P [] -> a :: l1 = []P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll1:list boolIHl1:forall l0 : list bool, length l1 = length l0 -> Y P l1 -> Y P l0 -> l1 = l0b:booll2:list boollength (a :: l1) = length (b :: l2) -> Y P (a :: l1) -> Y P (b :: l2) -> a :: l1 = b :: l2P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll1:list boolIHl1:forall l0 : list bool, length l1 = length l0 -> Y P l1 -> Y P l0 -> l1 = l0b:booll2:list boolH:length l1 = length l2HY1:Y P l1H1:if a then exists n : nat, inductively_barred_at P n (false :: l1) else infinite_from P (false :: l1)HY2:Y P l2H2:if b then exists n : nat, inductively_barred_at P n (false :: l2) else infinite_from P (false :: l2)a :: l1 = b :: l2P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll1:list boolIHl1:forall l0 : list bool, length l1 = length l0 -> Y P l1 -> Y P l0 -> l1 = l0b:booll2:list boolH:length l1 = length l2HY1:Y P l1H1:if a then exists n : nat, inductively_barred_at P n (false :: l1) else infinite_from P (false :: l1)HY2:Y P l2H2:if b then exists n : nat, inductively_barred_at P n (false :: l2) else infinite_from P (false :: l2)H0:l1 = l2a :: l1 = b :: l2P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll1:list boolb:booll2:list boolH1:if a then exists n : nat, inductively_barred_at P n (false :: l1) else infinite_from P (false :: l1)H2:if b then exists n : nat, inductively_barred_at P n (false :: l2) else infinite_from P (false :: l2)H0:l1 = l2a :: l1 = b :: l2P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa, b:booll2:list boolH1:if a then exists n : nat, inductively_barred_at P n (false :: l2) else infinite_from P (false :: l2)H2:if b then exists n : nat, inductively_barred_at P n (false :: l2) else infinite_from P (false :: l2)a :: l2 = b :: l2P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa, b:booll2:list boolH1:if a then exists n : nat, inductively_barred_at P n (false :: l2) else infinite_from P (false :: l2)H2:if b then exists n : nat, inductively_barred_at P n (false :: l2) else infinite_from P (false :: l2)a = bP:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl2:list boolH1:exists n : nat, inductively_barred_at P n (false :: l2)H2:infinite_from P (false :: l2)true = falseP:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl2:list boolH1:infinite_from P (false :: l2)H2:exists n : nat, inductively_barred_at P n (false :: l2)false = trueP:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl2:list boolH1:exists n : nat, inductively_barred_at P n (false :: l2)H2:infinite_from P (false :: l2)true = falsedestruct (is_path_from_imp_inductively_barred_at _ _ _ (H2 n) Hbar).P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl2:list booln:natHbar:inductively_barred_at P n (false :: l2)H2:infinite_from P (false :: l2)true = falseP:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl2:list boolH1:infinite_from P (false :: l2)H2:exists n : nat, inductively_barred_at P n (false :: l2)false = truedestruct (is_path_from_imp_inductively_barred_at _ _ _ (H1 n) Hbar). Qed.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl2:list boolH1:infinite_from P (false :: l2)n:natHbar:inductively_barred_at P n (false :: l2)false = true
X is the translation of Y as a predicate
Definition X P n := exists l, length l = n /\ Y P (true::l).forall P : list bool -> Prop, demorgan_inductively_barred_at P -> forall l : list bool, approx (X P) l -> Y P lforall P : list bool -> Prop, demorgan_inductively_barred_at P -> forall l : list bool, approx (X P) l -> Y P lP:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pforall l : list bool, approx (X P) l -> Y P lP:list bool -> PropDeMorgan:demorgan_inductively_barred_at Papprox (X P) [] -> Y P []P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll:list boolIHl:approx (X P) l -> Y P lapprox (X P) (a :: l) -> Y P (a :: l)trivial.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Papprox (X P) [] -> Y P []P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll:list boolIHl:approx (X P) l -> Y P lapprox (X P) (a :: l) -> Y P (a :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:if a then X P (length l) else ~ X P (length l)Y P (a :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:if a then X P (length l) else ~ X P (length l)Y P lP:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:if a then X P (length l) else ~ X P (length l)if a then exists n : nat, inductively_barred_at P n (false :: l) else infinite_from P (false :: l)auto.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:if a then X P (length l) else ~ X P (length l)Y P lP:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:if a then X P (length l) else ~ X P (length l)if a then exists n : nat, inductively_barred_at P n (false :: l) else infinite_from P (false :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pa:booll:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:if a then exists l0 : list bool, length l0 = length l /\ Y P (true :: l0) else ~ (exists l0 : list bool, length l0 = length l /\ Y P (true :: l0))if a then exists n : nat, inductively_barred_at P n (false :: l) else infinite_from P (false :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:exists l0 : list bool, length l0 = length l /\ Y P (true :: l0)exists n : nat, inductively_barred_at P n (false :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:~ (exists l0 : list bool, length l0 = length l /\ Y P (true :: l0))infinite_from P (false :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:exists l0 : list bool, length l0 = length l /\ Y P (true :: l0)exists n : nat, inductively_barred_at P n (false :: l)rewrite <- (Y_unique P DeMorgan l' l Hl'); auto.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl:list boolIHl:approx (X P) l -> Y P lH:approx (X P) ll':list boolHl':length l' = length lHYl':Y P l'HY:exists n : nat, inductively_barred_at P n (false :: l')exists n : nat, inductively_barred_at P n (false :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:~ (exists l0 : list bool, length l0 = length l /\ Y P (true :: l0))infinite_from P (false :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:~ (exists l0 : list bool, length l0 = length l /\ Y P (true :: l0))n:natis_path_from P n (false :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:~ (exists l0 : list bool, length l0 = length l /\ Y P (true :: l0))n:natdemorgan_inductively_barred_at PP:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:~ (exists l0 : list bool, length l0 = length l /\ Y P (true :: l0))n:nat~ inductively_barred_at P n (false :: l)firstorder. Qed.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at Pl:list boolIHl:approx (X P) l -> Y P lH:approx (X P) lHb:~ (exists l0 : list bool, length l0 = length l /\ Y P (true :: l0))n:nat~ inductively_barred_at P n (false :: l)
Main theorem
forall P : list bool -> Prop, demorgan_inductively_barred_at P -> infinite_from P [] -> has_infinite_path Pforall P : list bool -> Prop, demorgan_inductively_barred_at P -> infinite_from P [] -> has_infinite_path PP:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []has_infinite_path PP:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []forall l : list bool, approx (X P) l -> ~ P lP:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:approx (X P) l~ P lP:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:approx (X P) linfinite_from P lP:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:approx (X P) lH:infinite_from P l~ P lP:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:approx (X P) linfinite_from P lP:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []Hl:approx (X P) []infinite_from P []P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []a:booll:list boolHl:approx (X P) (a :: l)IHl:approx (X P) l -> infinite_from P linfinite_from P (a :: l)assumption.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []Hl:approx (X P) []infinite_from P []P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []a:booll:list boolHl:approx (X P) (a :: l)IHl:approx (X P) l -> infinite_from P linfinite_from P (a :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []a:booll:list boolHl:approx (X P) lHa:if a then X P (length l) else ~ X P (length l)IHl:approx (X P) l -> infinite_from P linfinite_from P (a :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []a:booll:list boolHl:approx (X P) lHa:if a then X P (length l) else ~ X P (length l)IHl:approx (X P) l -> infinite_from P ln:natis_path_from P n (a :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []a:booll:list boolHl:approx (X P) lHa:if a then X P (length l) else ~ X P (length l)IHl:approx (X P) l -> infinite_from P ln:natIHl':infinite_from P lis_path_from P n (a :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []a:booll:list boolHl:approx (X P) lHa:if a then X P (length l) else ~ X P (length l)n:natIHl':infinite_from P lis_path_from P n (a :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []a:booll:list boolHl:Y P lHa:if a then X P (length l) else ~ X P (length l)n:natIHl':infinite_from P lis_path_from P n (a :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P lHa:X P (length l)n:natIHl':infinite_from P lis_path_from P n (true :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P lHa:~ X P (length l)n:natIHl':infinite_from P lis_path_from P n (false :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P lHa:X P (length l)n:natIHl':infinite_from P lis_path_from P n (true :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P ll':list boolHl':length l' = length lHY':Y P l'n':natHbar:inductively_barred_at P n' (false :: l')n:natIHl':infinite_from P lis_path_from P n (true :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P ll':list boolHl':length l' = length lHY':Y P l'n':natHbar:inductively_barred_at P n' (false :: l)n:natIHl':infinite_from P lis_path_from P n (true :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P ll':list boolHl':length l' = length lHY':Y P l'n':natHbar:inductively_barred_at P n' (false :: l)n:natIHl':infinite_from P lHle:n <= n'is_path_from P n (true :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P ll':list boolHl':length l' = length lHY':Y P l'n':natHbar:inductively_barred_at P n' (false :: l)n:natIHl':infinite_from P lHlt:n' < nis_path_from P n (true :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P ll':list boolHl':length l' = length lHY':Y P l'n':natHbar:inductively_barred_at P n' (false :: l)n:natIHl':infinite_from P lHle:n <= n'is_path_from P n (true :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P ll':list boolHl':length l' = length lHY':Y P l'n':natHbar:inductively_barred_at P n' (false :: l)n:natIHl':is_path_from P (S n') lHle:n <= n'is_path_from P n (true :: l)apply find_left_path; trivial.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P ll':list boolHl':length l' = length lHY':Y P l'n':natHbar:inductively_barred_at P n' (false :: l)n:natIHl':is_path_from P (S n') lHle:n <= n'is_path_from P n' (true :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P ll':list boolHl':length l' = length lHY':Y P l'n':natHbar:inductively_barred_at P n' (false :: l)n:natIHl':infinite_from P lHlt:n' < nis_path_from P n (true :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P ll':list boolHl':length l' = length lHY':Y P l'n':natHbar:inductively_barred_at P n' (false :: l)n:natIHl':is_path_from P (S n) lHlt:n' < nis_path_from P n (true :: l)apply find_left_path; trivial.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P ll':list boolHl':length l' = length lHY':Y P l'n', n:natHbar:inductively_barred_at P n (false :: l)IHl':is_path_from P (S n) lHlt:n' < nis_path_from P n (true :: l)apply inductively_barred_at_imp_is_path_from; firstorder.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:Y P lHa:~ X P (length l)n:natIHl':infinite_from P lis_path_from P n (false :: l)P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:approx (X P) lH:infinite_from P l~ P lP:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:approx (X P) lH:is_path_from P 0 l~ P lassumption. Qed.P:list bool -> PropDeMorgan:demorgan_inductively_barred_at PHinf:infinite_from P []l:list boolHl:approx (X P) lH:is_path_from P 0 ll0:list boolH0:~ P lH2:l0 = l~ P lforall P : list bool -> Prop, (forall l : list bool, P l \/ ~ P l) -> forall (n : nat) (l : list bool), inductively_barred_at P n l \/ ~ inductively_barred_at P n lforall P : list bool -> Prop, (forall l : list bool, P l \/ ~ P l) -> forall (n : nat) (l : list bool), inductively_barred_at P n l \/ ~ inductively_barred_at P n lP:list bool -> PropHP:forall l : list bool, P l \/ ~ P lforall (n : nat) (l : list bool), inductively_barred_at P n l \/ ~ inductively_barred_at P n lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0l:list boolinductively_barred_at P 0 l \/ ~ inductively_barred_at P 0 lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolinductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0l:list boolinductively_barred_at P 0 l \/ ~ inductively_barred_at P 0 lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0l:list boolH:P linductively_barred_at P 0 l \/ ~ inductively_barred_at P 0 lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0l:list boolH:~ P linductively_barred_at P 0 l \/ ~ inductively_barred_at P 0 lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0l:list boolH:P linductively_barred_at P 0 l \/ ~ inductively_barred_at P 0 lapply now_at, H.P:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0l:list boolH:P linductively_barred_at P 0 lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0l:list boolH:~ P linductively_barred_at P 0 l \/ ~ inductively_barred_at P 0 lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0l:list boolH:~ P l~ inductively_barred_at P 0 lauto.P:list bool -> PropHP:forall l1 : list bool, P l1 \/ ~ P l1l:list boolH:~ P lH0:inductively_barred_at P 0 ll0:list booln:natH1:P lH2:n = 0H3:l0 = lFalseP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolinductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:P linductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P linductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:P linductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lapply now_at, H.P:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:P linductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P linductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:inductively_barred_at P n (true :: l)inductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:~ inductively_barred_at P n (true :: l)inductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:inductively_barred_at P n (true :: l)inductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:inductively_barred_at P n (true :: l)H1:inductively_barred_at P n (false :: l)inductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:inductively_barred_at P n (true :: l)H1:~ inductively_barred_at P n (false :: l)inductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:inductively_barred_at P n (true :: l)H1:inductively_barred_at P n (false :: l)inductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lapply propagate_at; assumption.P:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:inductively_barred_at P n (true :: l)H1:inductively_barred_at P n (false :: l)inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:inductively_barred_at P n (true :: l)H1:~ inductively_barred_at P n (false :: l)inductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:inductively_barred_at P n (true :: l)H1:~ inductively_barred_at P n (false :: l)inductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) linversion_clear 1; auto. }P:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:inductively_barred_at P n (true :: l)H1:~ inductively_barred_at P n (false :: l)~ inductively_barred_at P (S n) lP:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:~ inductively_barred_at P n (true :: l)inductively_barred_at P (S n) l \/ ~ inductively_barred_at P (S n) linversion_clear 1; auto. Qed.P:list bool -> PropHP:forall l0 : list bool, P l0 \/ ~ P l0n:natIHn:forall l0 : list bool, inductively_barred_at P n l0 \/ ~ inductively_barred_at P n l0l:list boolH:~ P lH0:~ inductively_barred_at P n (true :: l)~ inductively_barred_at P (S n) lforall P : list bool -> Prop, (forall l : list bool, P l \/ ~ P l) -> demorgan_inductively_barred_at Pforall P : list bool -> Prop, (forall l : list bool, P l \/ ~ P l) -> demorgan_inductively_barred_at PP:list bool -> PropHdec:forall l0 : list bool, P l0 \/ ~ P l0n:natl:list boolH:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))~ inductively_barred_at P n (true :: l) \/ ~ inductively_barred_at P n (false :: l)P:list bool -> PropHdec:forall l0 : list bool, P l0 \/ ~ P l0n:natl:list boolH:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))H0:inductively_barred_at P n (true :: l)~ inductively_barred_at P n (true :: l) \/ ~ inductively_barred_at P n (false :: l)P:list bool -> PropHdec:forall l0 : list bool, P l0 \/ ~ P l0n:natl:list boolH:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))H0:~ inductively_barred_at P n (true :: l)~ inductively_barred_at P n (true :: l) \/ ~ inductively_barred_at P n (false :: l)P:list bool -> PropHdec:forall l0 : list bool, P l0 \/ ~ P l0n:natl:list boolH:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))H0:inductively_barred_at P n (true :: l)~ inductively_barred_at P n (true :: l) \/ ~ inductively_barred_at P n (false :: l)P:list bool -> PropHdec:forall l0 : list bool, P l0 \/ ~ P l0n:natl:list boolH:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))H0:inductively_barred_at P n (true :: l)H1:inductively_barred_at P n (false :: l)~ inductively_barred_at P n (true :: l) \/ ~ inductively_barred_at P n (false :: l)P:list bool -> PropHdec:forall l0 : list bool, P l0 \/ ~ P l0n:natl:list boolH:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))H0:inductively_barred_at P n (true :: l)H1:~ inductively_barred_at P n (false :: l)~ inductively_barred_at P n (true :: l) \/ ~ inductively_barred_at P n (false :: l)auto.P:list bool -> PropHdec:forall l0 : list bool, P l0 \/ ~ P l0n:natl:list boolH:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))H0:inductively_barred_at P n (true :: l)H1:inductively_barred_at P n (false :: l)~ inductively_barred_at P n (true :: l) \/ ~ inductively_barred_at P n (false :: l)auto.P:list bool -> PropHdec:forall l0 : list bool, P l0 \/ ~ P l0n:natl:list boolH:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))H0:inductively_barred_at P n (true :: l)H1:~ inductively_barred_at P n (false :: l)~ inductively_barred_at P n (true :: l) \/ ~ inductively_barred_at P n (false :: l)auto. Qed.P:list bool -> PropHdec:forall l0 : list bool, P l0 \/ ~ P l0n:natl:list boolH:~ (inductively_barred_at P n (true :: l) /\ inductively_barred_at P n (false :: l))H0:~ inductively_barred_at P n (true :: l)~ inductively_barred_at P n (true :: l) \/ ~ inductively_barred_at P n (false :: l)
Main corollary
forall P : list bool -> Prop, (forall l : list bool, P l \/ ~ P l) -> infinite_from P [] -> has_infinite_path Pforall P : list bool -> Prop, (forall l : list bool, P l \/ ~ P l) -> infinite_from P [] -> has_infinite_path PP:list bool -> PropHdec:forall l : list bool, P l \/ ~ P lHinf:infinite_from P []has_infinite_path Papply PreWeakKonigsLemma; assumption. Qed.P:list bool -> PropHdec:demorgan_inductively_barred_at PHinf:infinite_from P []has_infinite_path P