Library Base

Base Library for ICL

  • Author: Gert Smolka, Saarland University
  • Version: 4 June 2014


GlobalGlobal




Iteration


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 → (∀ 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 :
    (∀ n, FP (it n x) ∨ sigma (it n x) > sigma (it (S n) x)) →
    FP (it (sigma x) x).
End Iteration.

Decidability


Definition dec (X : Prop) : Type := {X} + {¬ X}.

Notation "'eq_dec' X" := (∀ 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.






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.

Lists



Definition equi X (A B : list X) : Prop :=
  incl A B ∧ incl B A.


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).



Lemma list_cycle (X : Type) (A : list X) x :
  x::A ≠ A.

Decidability laws for lists

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 : ∀ x, dec (p x)) :
  {x | x ∊ A ∧ p x} + {∀ x, x ∊ A → ¬ p x}.


Instance list_forall_dec X A (p : X → Prop) (p_dec : ∀ x, dec (p x)) :
  dec (∀ x, x ∊ A → p x).

Instance list_exists_dec X A (p : X → Prop) (p_dec : ∀ x, dec (p x)) :
  dec (∃ x, x ∊ A ∧ p x).

Lemma list_exists_DM X A (p : X → Prop) :
  (∀ x, dec (p x)) →
  ¬ (∀ x, x ∊ A → ¬ p x) → ∃ x, x ∊ A ∧ p x.

Lemma list_cc X (p : X → Prop) A :
  (∀ x, dec (p x)) →
  (∃ x, x ∊ A ∧ p x) → {x | x ∊ A ∧ p x}.

Membership
We use the following facts from the standard library List.


Lemma in_sing X (x y : X) :
  x ∊ [y] → x = y.

Lemma in_cons_neq X (x y : X) A :
  x ∊ y::A → x ≠ y → x ∊ A.

Definition disjoint (X : Type) (A B : list X) :=
  ¬ ∃ x, x ∊ A ∧ x ∊ B.

Lemma disjoint_forall X (A B : list X) :
  disjoint A B ↔ ∀ x, x ∊ A → ¬ x ∊ B.

Lemma disjoint_cons X (x : X) A B :
  disjoint (x::A) B ↔ ¬ x ∊ B ∧ disjoint A B.

Inclusion
We use the following facts from the standard library List.


Lemma incl_nil X (A : list X) :
  nil ⊆ A.


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_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.

End Inclusion.


Definition inclp (X : Type) (A : list X) (p : X → Prop) : Prop :=
  ∀ x, x ∊ A → p x.

Setoid rewriting with list inclusion and list equivalence

Instance in_equi_proper X :
  Proper (eq ==> @equi X ==> iff) (@In X).


Instance incl_equi_proper X :
  Proper (@equi X ==> @equi X ==> iff) (@incl X).


Instance incl_preorder X : PreOrder (@incl X).


Instance equi_Equivalence X : Equivalence (@equi X).


Instance cons_equi_proper X :
  Proper (eq ==> @equi X ==> @equi X) (@cons X).


Instance app_equi_proper X :
  Proper (@equi X ==> @equi X ==> @equi X) (@app X).


Equivalence

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.

Filter


Definition filter (X : Type) (p : X → Prop) (p_dec : ∀ 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 : ∀ 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_fst x A :
    p x → filter p (x::A) = x::filter p 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) = filter p A.

End FilterLemmas.

Section FilterLemmas_pq.
  Variable X : Type.
  Variable p q : X → Prop.
  Context {p_dec : ∀ x, dec (p x)}.
  Context {q_dec : ∀ x, dec (q x)}.

  Lemma filter_pq_mono A :
    (∀ x, x ∊ A → p x → q x) → filter p A ⊆ filter q A.

  Lemma filter_pq_eq A :
    (∀ 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 : ∀ x, dec (p x)}.
  Context {q_dec : ∀ x, dec (q x)}.

  Lemma filter_comm A :
    filter p (filter q A) = filter q (filter p A).
End FilterComm.

Element removal


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.

End Removal.


Duplicate-free lists


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_inv 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) :
    (∀ x y, x ∊ A → y ∊ A → f x = f y → x=y) →
    dupfree A → dupfree (map f A).

  Lemma dupfree_filter p (p_dec : ∀ x, dec (p x)) A :
    dupfree A → dupfree (filter p A).

  Lemma dupfree_dec A :
    eq_dec X → dec (dupfree 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_fp_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_eq A :
    dupfree A → undup A = A.

  Lemma undup_idempotent A :
    undup (undup A) = undup A.

End Undup.

Section DupfreeLength.
  Variable X : Type.
  Implicit Types A B : list X.

  Lemma dupfree_reorder A x :
    dupfree A → x ∊ A →
    ∃ A', A ≡ x::A' ∧ |A'| < |A| ∧ dupfree (x::A').
  Lemma dupfree_le A B :
    dupfree A → dupfree B → A ⊆ B → |A| ≤ |B|.

  Lemma dupfree_eq A B :
    dupfree A → dupfree B → A ≡ B → |A|=|B|.

  Lemma dupfree_lt A B x :
    dupfree A → dupfree B → A ⊆ B →
    x ∊ B → ¬ x ∊ A → |A| < |B|.

  Lemma dupfree_ex A B :
    eq_dec X → dupfree A → dupfree B → |A| < |B| → ∃ x, x ∊ B ∧ ¬ x ∊ A.

  Lemma dupfree_equi A B :
    eq_dec X → dupfree A → dupfree B → A ⊆ B → |A|=|B| → A ≡ B.

End DupfreeLength.

Cardinality


Section Cardinality.
  Variable X : Type.
  Context {eq_X_dec : eq_dec X}.
  Implicit Types A B : list X.

  Definition card (A : list X) : nat := |undup A|.

  Lemma card_le A B :
    A ⊆ B → card A ≤ card B.

  Lemma card_eq A B :
    A ≡ B → card A = card B.

  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.

  Lemma card_ex A B :
    card A < card B → ∃ x, x ∊ B ∧ ¬ x ∊ A.

  Lemma card_cons x A :
    card (x::A) = if decision (x ∊ A) then card A else 1 + card A.

  Lemma card_cons_rem x A :
    card (x::A) = 1 + card (rem A x).

  Lemma card_0 A :
    card A = 0 → A = nil.

End Cardinality.

Instance card_equi_proper X (D: eq_dec X) :
  Proper (@equi X ==> eq) (@card X D).

Power lists


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 :
    (∀ 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.

Finite closure iteration


Module FCI.
Section FCI.
  Variable X : Type.
  Context {eq_X_dec : eq_dec X}.
  Variable step : list X → X → Prop.
  Context {step_dec : ∀ A x, dec (step A x)}.
  Variable V : list X.

  Lemma pick (A : list X) :
    { x | x ∊ V ∧ step A x ∧ ¬ x ∊ A } + { ∀ 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 :
    (∀ 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.

Lemma complete_induction (p : nat → Prop) (x : nat) :
(∀ x, (∀ y, y<x → p y) → p x) → p x.

Lemma size_induction X (f : X → nat) (p : X → Prop) :
  (∀ x, (∀ y, f y < f x → p y) → p x) →
  ∀ x, p x.

Section pos.

  Definition elAt := nth_error.
  Notation "A '.[' i ']'" := (elAt A i) (no associativity, at level 50).

  Fixpoint pos (X : Type) {e : eq_dec X} (s : X) (A : list X) :=
    match A with
      | nil ⇒ None
      | a :: A ⇒ if decision (s = a) then Some 0 else match pos s A with None ⇒ None | Some n ⇒ Some (S n) end
    end.

  Lemma el_pos X (E : eq_dec X) s A : s ∊ A → ∃ m, pos s A = Some m.

  Lemma pos_elAt X (_ : eq_dec X) s A i : pos s A = Some i → A .[i] = Some s.

  Lemma elAt_app X (A : list X) i B s : A .[i] = Some s → (A ++ B).[i] = Some s.

  Lemma elAt_el (X : Type) A (s : X) m : A .[ m ] = Some s → s ∊ A.

  Lemma el_elAt X {_ : eq_dec X} (s : X) A : s ∊ A → ∃ m, A .[ m ] = Some s.

Lemma dupfree_elAt X (A : list X) n m s : dupfree A → A.[n] = Some s → A.[m] = Some s → n = m.

Lemma nth_error_none A n l : nth_error l n = @None A → length l ≤ n.

End pos.