Library Base
Base Library for ICL
- Version: 30 June 2014
- Author: Gert Smolka, Saarland University
- Acknowlegments: Sigurd Schneider, Dominik Kirst
Global Set Implicit Arguments.
Global
Require Export Omega List Morphisms.
Ltac inv H := inversion H; subst; clear H.
Lemma DM_or (X Y : Prop) :
~ (X \/ Y) <-> ~ X /\ ~ Y.
Lemma DM_exists X (p : X -> Prop) :
~ (exists x, p x) <-> forall x, ~ p x.
Lemma size_recursion (X : Type) (sigma : X -> nat) (p : X -> Type) :
(forall x, (forall y, sigma y < sigma x -> p y) -> p x) ->
forall x, p x.
Section Iteration.
Variable X : Type.
Variable f : X -> X.
Fixpoint it (n : nat) (x : X) : X :=
match n with
| 0 => x
| S n' => f (it n' x)
end.
Lemma it_ind (p : X -> Prop) x n :
p x -> (forall z, p z -> p (f z)) -> p (it n x).
Definition FP (x : X) : Prop := f x = x.
Lemma it_fp (sigma : X -> nat) x :
(forall n, FP (it n x) \/ sigma (it n x) > sigma (it (S n) x)) ->
FP (it (sigma x) x).
End Iteration.
Definition dec (X : Prop) : Type := {X} + {~ X}.
Notation "'eq_dec' X" := (forall x y : X, dec (x=y)) (at level 70).
Definition decision (X : Prop) (D : dec X) : dec X := D.
Tactic Notation "decide" constr(p) :=
destruct (decision p).
Tactic Notation "decide" constr(p) "as" simple_intropattern(i) :=
destruct (decision p) as i.
Hint Extern 4 =>
match goal with
| [ |- dec ?p ] => exact (decision p)
end.
Hint Extern 4 =>
match goal with
| [ |- dec ((fun _ => _) _) ] => simpl
end : typeclass_instances.
Instance True_dec : dec True :=
left I.
Instance False_dec : dec False :=
right (fun A => A).
Instance impl_dec (X Y : Prop) :
dec X -> dec Y -> dec (X -> Y).
Instance and_dec (X Y : Prop) :
dec X -> dec Y -> dec (X /\ Y).
Instance or_dec (X Y : Prop) :
dec X -> dec Y -> dec (X \/ Y).
Instance not_dec (X : Prop) :
dec X -> dec (~ X).
Instance iff_dec (X Y : Prop) :
dec X -> dec Y -> dec (X <-> Y).
Lemma dec_DN X :
dec X -> ~~ X -> X.
Lemma dec_DM_and X Y :
dec X -> dec Y -> ~ (X /\ Y) -> ~ X \/ ~ Y.
Lemma dec_DM_impl X Y :
dec X -> dec Y -> ~ (X -> Y) -> X /\ ~ Y.
Lemma dec_prop_iff (X Y : Prop) :
(X <-> Y) -> dec X -> dec Y.
Instance bool_eq_dec :
eq_dec bool.
Instance nat_eq_dec :
eq_dec nat.
Instance nat_le_dec (x y : nat) : dec (x <= y) :=
le_dec x y.
Definition equi X (A B : list X) : Prop :=
incl A B /\ incl B A.
Hint Unfold equi.
Export ListNotations.
Notation "| A |" := (length A) (at level 65).
Notation "x 'el' A" := (In x A) (at level 70).
Notation "A <<= B" := (incl A B) (at level 70).
Notation "A === B" := (equi A B) (at level 70).
Register additional simplification rules with autorewrite / simpl_list
Hint Rewrite <- app_assoc : list.
Hint Rewrite rev_app_distr map_app prod_length : list.
Lemma list_cycle (X : Type) (A : list X) x :
x::A <> A.
Instance list_eq_dec X :
eq_dec X -> eq_dec (list X).
Instance list_in_dec (X : Type) (x : X) (A : list X) :
eq_dec X -> dec (x ∊ A).
Lemma list_sigma_forall X A (p : X -> Prop) (p_dec : forall x, dec (p x)) :
{x | x ∊ A /\ p x} + {forall x, x ∊ A -> ~ p x}.
Instance list_forall_dec X A (p : X -> Prop) :
(forall x, dec (p x)) -> dec (forall x, x ∊ A -> p x).
Instance list_exists_dec X A (p : X -> Prop) :
(forall x, dec (p x)) -> dec (exists x, x ∊ A /\ p x).
Lemma list_exists_DM X A (p : X -> Prop) :
(forall x, dec (p x)) ->
~ (forall x, x ∊ A -> ~ p x) -> exists x, x ∊ A /\ p x.
Lemma list_exists_not_incl X (A B : list X) :
eq_dec X ->
~ A ⊆ B -> exists x, x ∊ A /\ ~ x ∊ B.
Lemma list_cc X (p : X -> Prop) A :
(forall x, dec (p x)) ->
(exists x, x ∊ A /\ p x) -> {x | x ∊ A /\ p x}.
Membership
- in_eq : x ∊ x::A
- in_nil : ~ x ∊ nil
- in_cons : x ∊ A -> x ∊ y::A
- in_or_app : x ∊ A \/ x ∊ B -> x ∊ A++B
- in_app_iff : x ∊ A++B <-> x ∊ A \/ x ∊ B
- in_map_iff : y ∊ map f A <-> exists x, f x = y /\ x ∊ A
Hint Resolve in_eq in_nil in_cons in_or_app.
Section Membership.
Variable X : Type.
Implicit Types x y : X.
Implicit Types A B : list X.
Lemma in_sing x y :
x ∊ [y] -> x = y.
Lemma in_cons_neq x y A :
x ∊ y::A -> x <> y -> x ∊ A.
Lemma not_in_cons x y A :
~ x ∊ y :: A -> x <> y /\ ~ x ∊ A.
Definition disjoint A B :=
~ exists x, x ∊ A /\ x ∊ B.
Lemma disjoint_forall A B :
disjoint A B <-> forall x, x ∊ A -> ~ x ∊ B.
Lemma disjoint_symm A B :
disjoint A B -> disjoint B A.
Lemma disjoint_incl A B B' :
B' ⊆ B -> disjoint A B -> disjoint A B'.
Lemma disjoint_nil B :
disjoint nil B.
Lemma disjoint_nil' A :
disjoint A nil.
Lemma disjoint_cons x A B :
disjoint (x::A) B <-> ~ x ∊ B /\ disjoint A B.
Lemma disjoint_app A B C :
disjoint (A ++ B) C <-> disjoint A C /\ disjoint B C.
End Membership.
Hint Resolve disjoint_nil disjoint_nil'.
Inclusion
- incl_refl : A ⊆ A
- incl_tl : A ⊆ B -> A ⊆ x::B
- incl_cons : x ∊ B -> A ⊆ B -> x::A ⊆ B
- incl_appl : A ⊆ B -> A ⊆ B++C
- incl_appr : A ⊆ C -> A ⊆ B++C
- incl_app : A ⊆ C -> B ⊆ C -> A++B ⊆ C
Hint Resolve incl_refl incl_tl incl_cons incl_appl incl_appr incl_app.
Lemma incl_nil X (A : list X) :
nil ⊆ A.
Hint Resolve incl_nil.
Lemma incl_map X Y A B (f : X -> Y) :
A ⊆ B -> map f A ⊆ map f B.
Section Inclusion.
Variable X : Type.
Implicit Types A B : list X.
Lemma incl_nil_eq A :
A ⊆ nil -> A=nil.
Lemma incl_shift x A B :
A ⊆ B -> x::A ⊆ x::B.
Lemma incl_lcons x A B :
x::A ⊆ B <-> x ∊ B /\ A ⊆ B.
Lemma incl_sing x A y :
x::A ⊆ [y] -> x = y /\ A ⊆ [y].
Lemma incl_rcons x A B :
A ⊆ x::B -> ~ x ∊ A -> A ⊆ B.
Lemma incl_lrcons x A B :
x::A ⊆ x::B -> ~ x ∊ A -> A ⊆ B.
Lemma incl_app_left A B C :
A ++ B ⊆ C -> A ⊆ C /\ B ⊆ C.
End Inclusion.
Definition inclp (X : Type) (A : list X) (p : X -> Prop) : Prop :=
forall x, x ∊ A -> p x.
Instance incl_preorder X :
PreOrder (@incl X).
Instance equi_Equivalence X :
Equivalence (@equi X).
Instance incl_equi_proper X :
Proper (@equi X ==> @equi X ==> iff) (@incl X).
Instance cons_incl_proper X x :
Proper (@incl X ==> @incl X) (@cons X x).
Instance cons_equi_proper X x :
Proper (@equi X ==> @equi X) (@cons X x).
Instance in_incl_proper X x :
Proper (@incl X ==> Basics.impl) (@In X x).
Instance in_equi_proper X x :
Proper (@equi X ==> iff) (@In X x).
Instance app_incl_proper X :
Proper (@incl X ==> @incl X ==> @incl X) (@app X).
Instance app_equi_proper X :
Proper (@equi X ==> @equi X ==> @equi X) (@app X).
Section Equi.
Variable X : Type.
Implicit Types A B : list X.
Lemma equi_push x A :
x ∊ A -> A ≡ x::A.
Lemma equi_dup x A :
x::A ≡ x::x::A.
Lemma equi_swap x y A:
x::y::A ≡ y::x::A.
Lemma equi_shift x A B :
x::A++B ≡ A++x::B.
Lemma equi_rotate x A :
x::A ≡ A++[x].
End Equi.
Definition filter (X : Type) (p : X -> Prop) (p_dec : forall x, dec (p x)) : list X -> list X :=
fix f A := match A with
| nil => nil
| x::A' => if decision (p x) then x :: f A' else f A'
end.
Section FilterLemmas.
Variable X : Type.
Variable p : X -> Prop.
Context {p_dec : forall x, dec (p x)}.
Lemma in_filter_iff x A :
x ∊ filter p A <-> x ∊ A /\ p x.
Lemma filter_incl A :
filter p A ⊆ A.
Lemma filter_mono A B :
A ⊆ B -> filter p A ⊆ filter p B.
Lemma filter_id A :
(forall x, x ∊ A -> p x) -> filter p A = A.
Lemma filter_app A B :
filter p (A ++ B) = filter p A ++ filter p B.
Lemma filter_fst x A :
p x -> filter p (x::A) = x::filter p A.
Lemma filter_fst' x A :
~ p x -> filter p (x::A) = filter p A.
End FilterLemmas.
Section FilterLemmas_pq.
Variable X : Type.
Variable p q : X -> Prop.
Context {p_dec : forall x, dec (p x)}.
Context {q_dec : forall x, dec (q x)}.
Lemma filter_pq_mono A :
(forall x, x ∊ A -> p x -> q x) -> filter p A ⊆ filter q A.
Lemma filter_pq_eq A :
(forall x, x ∊ A -> (p x <-> q x)) -> filter p A = filter q A.
Lemma filter_and A :
filter p (filter q A) = filter (fun x => p x /\ q x) A.
End FilterLemmas_pq.
Section FilterComm.
Variable X : Type.
Variable p q : X -> Prop.
Context {p_dec : forall x, dec (p x)}.
Context {q_dec : forall x, dec (q x)}.
Lemma filter_comm A :
filter p (filter q A) = filter q (filter p A).
End FilterComm.
Section Removal.
Variable X : Type.
Context {eq_X_dec : eq_dec X}.
Definition rem (A : list X) (x : X) : list X :=
filter (fun z => z <> x) A.
Lemma in_rem_iff x A y :
x ∊ rem A y <-> x ∊ A /\ x <> y.
Lemma rem_not_in x y A :
x = y \/ ~ x ∊ A -> ~ x ∊ rem A y.
Lemma rem_incl A x :
rem A x ⊆ A.
Lemma rem_mono A B x :
A ⊆ B -> rem A x ⊆ rem B x.
Lemma rem_cons A B x :
A ⊆ B -> rem (x::A) x ⊆ B.
Lemma rem_cons' A B x y :
x ∊ B -> rem A y ⊆ B -> rem (x::A) y ⊆ B.
Lemma rem_in x y A :
x ∊ rem A y -> x ∊ A.
Lemma rem_neq x y A :
x <> y -> x ∊ A -> x ∊ rem A y.
Lemma rem_app x A B :
x ∊ A -> B ⊆ A ++ rem B x.
Lemma rem_app' x A B C :
rem A x ⊆ C -> rem B x ⊆ C -> rem (A ++ B) x ⊆ C.
Lemma rem_equi x A :
x::A ≡ x::rem A x.
Lemma rem_comm A x y :
rem (rem A x) y = rem (rem A y) x.
Lemma rem_fst x A :
rem (x::A) x = rem A x.
Lemma rem_fst' x y A :
x <> y -> rem (x::A) y = x::rem A y.
Lemma rem_id x A :
~ x ∊ A -> rem A x = A.
Lemma rem_reorder x A :
x ∊ A -> A ≡ x :: rem A x.
Lemma rem_inclr A B x :
A ⊆ B -> ~ x ∊ A -> A ⊆ rem B x.
End Removal.
Hint Resolve rem_not_in rem_incl rem_mono rem_cons rem_cons' rem_app rem_app' rem_in rem_neq rem_inclr.
Section Cardinality.
Variable X : Type.
Context { eq_X_dec : eq_dec X }.
Implicit Types A B : list X.
Fixpoint card A :=
match A with
| nil => 0
| x::A => if decision (x ∊ A) then card A else 1 + card A
end.
Lemma card_in_rem x A :
x ∊ A -> card A = 1 + card (rem A x).
Lemma card_not_in_rem A x :
~ x ∊ A -> card A = card (rem A x).
Lemma card_le A B :
A ⊆ B -> card A <= card B.
Lemma card_eq A B :
A ≡ B -> card A = card B.
Lemma card_cons_rem x A :
card (x::A) = 1 + card (rem A x).
Lemma card_0 A :
card A = 0 -> A = nil.
Lemma card_ex A B :
card A < card B -> exists x, x ∊ B /\ ~ x ∊ A.
Lemma card_equi A B :
A ⊆ B -> card A = card B -> A ≡ B.
Lemma card_lt A B x :
A ⊆ B -> x ∊ B -> ~ x ∊ A -> card A < card B.
Lemma card_or A B :
A ⊆ B -> A ≡ B \/ card A < card B.
End Cardinality.
Instance card_equi_proper X (D: eq_dec X) :
Proper (@equi X ==> eq) (@card X D).
Inductive dupfree (X : Type) : list X -> Prop :=
| dupfreeN : dupfree nil
| dupfreeC x A : ~ x ∊ A -> dupfree A -> dupfree (x::A).
Section Dupfree.
Variable X : Type.
Implicit Types A B : list X.
Lemma dupfree_cons x A :
dupfree (x::A) <-> ~ x ∊ A /\ dupfree A.
Lemma dupfree_app A B :
disjoint A B -> dupfree A -> dupfree B -> dupfree (A++B).
Lemma dupfree_map Y A (f : X -> Y) :
(forall x y, x ∊ A -> y ∊ A -> f x = f y -> x=y) ->
dupfree A -> dupfree (map f A).
Lemma dupfree_filter p (p_dec : forall x, dec (p x)) A :
dupfree A -> dupfree (filter p A).
Lemma dupfree_dec A :
eq_dec X -> dec (dupfree A).
Lemma dupfree_card A (eq_X_dec : eq_dec X) :
dupfree A -> card A = |A|.
End Dupfree.
Section Undup.
Variable X : Type.
Context {eq_X_dec : eq_dec X}.
Implicit Types A B : list X.
Fixpoint undup (A : list X) : list X :=
match A with
| nil => nil
| x::A' => if decision (x ∊ A') then undup A' else x :: undup A'
end.
Lemma undup_id_equi A :
undup A ≡ A.
Lemma dupfree_undup A :
dupfree (undup A).
Lemma undup_incl A B :
A ⊆ B <-> undup A ⊆ undup B.
Lemma undup_equi A B :
A ≡ B <-> undup A ≡ undup B.
Lemma undup_id A :
dupfree A -> undup A = A.
Lemma undup_idempotent A :
undup (undup A) = undup A.
End Undup.
Section PowerRep.
Variable X : Type.
Context {eq_X_dec : eq_dec X}.
Fixpoint power (U : list X ) : list (list X) :=
match U with
| nil => [nil]
| x :: U' => power U' ++ map (cons x) (power U')
end.
Lemma power_incl A U :
A ∊ power U -> A ⊆ U.
Lemma power_nil U :
nil ∊ power U.
Definition rep (A U : list X) : list X :=
filter (fun x => x ∊ A) U.
Lemma rep_power A U :
rep A U ∊ power U.
Lemma rep_incl A U :
rep A U ⊆ A.
Lemma rep_in x A U :
A ⊆ U -> x ∊ A -> x ∊ rep A U.
Lemma rep_equi A U :
A ⊆ U -> rep A U ≡ A.
Lemma rep_mono A B U :
A ⊆ B -> rep A U ⊆ rep B U.
Lemma rep_eq' A B U :
(forall x, x ∊ U -> (x ∊ A <-> x ∊ B)) -> rep A U = rep B U.
Lemma rep_eq A B U :
A ≡ B -> rep A U = rep B U.
Lemma rep_injective A B U :
A ⊆ U -> B ⊆ U -> rep A U = rep B U -> A ≡ B.
Lemma rep_idempotent A U :
rep (rep A U) U = rep A U.
Lemma dupfree_power U :
dupfree U -> dupfree (power U).
Lemma dupfree_in_power U A :
A ∊ power U -> dupfree U -> dupfree A.
Lemma rep_dupfree A U :
dupfree U -> A ∊ power U -> rep A U = A.
Lemma power_extensional A B U :
dupfree U -> A ∊ power U -> B ∊ power U -> A ≡ B -> A = B.
End PowerRep.
Module FCI.
Section FCI.
Variable X : Type.
Context {eq_X_dec : eq_dec X}.
Variable step : list X -> X -> Prop.
Context {step_dec : forall A x, dec (step A x)}.
Variable V : list X.
Lemma pick (A : list X) :
{ x | x ∊ V /\ step A x /\ ~ x ∊ A } + { forall x, x ∊ V -> step A x -> x ∊ A }.
Definition F (A : list X) : list X.
Defined.
Definition C := it F (card V) nil.
Lemma it_incl n :
it F n nil ⊆ V.
Lemma incl :
C ⊆ V.
Lemma ind p :
(forall A x, inclp A p -> x ∊ V -> step A x -> p x) -> inclp C p.
Lemma fp :
F C = C.
Lemma closure x :
x ∊ V -> step C x -> x ∊ C.
End FCI.
End FCI.