Definition le: nat -> nat -> Prop := fun a: nat => fun b: nat => fun c: nat => exists c: nat, (eq b (plus a c))).
Definition lt: nat -> nat -> Prop := fun a: nat => fun b: nat => (le a b) /\ ~(eq a b).
Inductive list: Set -> Set := nil : forall A: Set, (list A) | cons: forall A: Set, A -> (list A) -> (list A).L'insieme A è un parametro comune a tutti i costruttori. Una variante di Inductive permette di rendere esplicito tale fatto:
Inductive list (A: Set): Set := nil : (list A) | cons: A -> (list A) -> (list A).La lista [1] è rappresentata come:
Check (cons nat (S O) (nil nat)). (cons nat (S O) (nil nat)) : (list nat)
Inductive le: nat -> nat -> Prop := leN: forall n: nat, (le n n) | leS: forall n: nat, forall m: nat, (le n m) -> (le n (S m)).
Inductive lt: nat -> nat -> Prop := ltN: forall n: nat, (lt n (S n)) | ltS: forall n: nat, forall m: nat, (lt n m) -> (lt n (S m)).
Inductive Odd: nat -> Prop := Odd1 : (Odd (S O)) | OddSS: forall n: nat, (Odd n) -> (Odd (S (S n))).
Inductive btree: Set := Leaf: nat -> btree | Node: btree -> btree -> btree.
Inductive checkB: btree -> Prop := CheckLeaf : forall n: nat, (checkB (Leaf n)) | CheckNode0: forall n1: nat, forall n2: nat, (checkB (Node (Leaf n1) (Leaf n2))) | CheckNode1: forall b1: btree, forall b2: btree, forall b3: btree, forall b4: btree, (checkB (Node b1 b2))-> (checkB (Node b3 b4))-> (checkB (Node (Node b1 b2) (Node b3 b4))).
Inductive bin: Set := end: bin | zero: bin -> bin | one: bin -> bin.
Inductive Full: bin -> Prop := FBa: (Full (one end)) | FRi: forall b: bin, (Full b) -> (Full (one b)).
Parameter node: Set.supponendo l'esistenza di un predicato Edge che mette in relazione due nodi. (Edge a b) significa che c'è una freccia da a verso b:
Parameter Edge: node -> node -> Prop.definire
Definition Neighbour: node->node->Prop := fun a: node => fun b: node => exists x: node, (Edge x a) /\ (Edge x b). Inductive Connected: node->node->Prop := Connected_Edge: forall a: node, forall b: node, (Edge a b) -> (Connected a b) | Connected_trans: forall a: node, forall b: node, forall c: node, (Edge a b) -> (Connected b c) -> (Connected a c).
Inductive between: nat -> nat -> nat -> Prop := between_O: forall n: nat, (between n n n) | between_S1: forall n: nat, forall m: nat, forall p: nat, (between n m p) -> (between n (S m) (S p)) | between_S2: forall n: nat, forall m: nat, forall p: nat, (between n m p) -> (between n m (S p))
Definition andb: bool -> bool -> bool := fun a: bool => fun b: bool => match a with true => b | false => false end.
Definition orb: bool -> bool -> bool := fun a: bool => fun b: bool => match a with true => true | false => b end.
Fixpoint length (A: Set) (l: (list A)) {struct l}: nat := match l with nil => O | (cons _ _ l1) => (S (length A l1)) end.
Fixpoint max (a: nat) (b: nat) {struct a}: nat := match a with O => b | (S a1) => match b1 with O => a | (S b1) => (S (max a1 b1)) end end.
Fixpoint ominus (a: nat) (b: nat) {struct a}: nat := match a with O => b | (S a1) => match b with O => a | (S b1) => (ominus a1 b1) end end.
Fixpoint bmax (a: btree) {struct a}: nat := match a with (Leaf b) => b | (Node b c) => (max (bmax b) (bmax c)) end.
Fixpoint byte (a: bin) {struct a}: nat := match a with end => O | (one a1) => (S (byte a1)) | (zero a1) => (S (byte a1)) end.
Fixpoint bval (a: bin) {struct a}: nat := match a with end => O | (one a1) => (S (plus (bvar a1) (bvar a1))) | (zero a1) => (plus (bvar a1) (bvar a1)) end.
Fixpoint le (n: nat) (m: nat) {struct n}: Prop := match n with O => True | (S n1) => match m with O => False | (S m1) => (le n1 m1) end end.
Fixpoint lt (n: nat) (m: nat) {struct n}: Prop := match n with O => match m with O => False | (S m1) => True end | (S n1) => match m with O => False | (S m1) => (lt n1 m1) end end.
Fixpoint Odd (n: nat) {struct n}: Prop := match n with O => False | (S O) => True | (S (S n1)) => (Odd n1) end.
Definition and_com: forall A: Prop, forall B: Prop, (A /\ B) -> (B /\ A) := fun A: Prop => fun B: Prop => fun H: (A /\ B) => match H with (conj H1 H2) => (conj B A H2 H1) end.
Definition or_com: forall A: Prop, forall B: Prop, (A \/ B) -> (B \/ A) := fun A: Prop => fun B: Prop => fun H: (A \/ B) => match H with (or_introl H1) => (or_intror B A H1) | (or_intror H1) => (or_introl B A H1) end.
Definition double: forall A: Prop, A -> (A /\ A) := fun A: Prop => fun H: A => (conj A A H).
Definition mpc: forall A: Prop, forall B: Prop, (A -> B) -> A -> (A /\ B) := fun A: Prop => fun B: Prop => fun H: A -> B => fun H1: A => (conj A B H1 (H H1)).
Definition cumul: forall A: Prop, forall B: Prop, forall C: Prop, (A -> B) -> (A -> C) -> A -> (B /\ C) := fun A: Prop => fun B: Prop => fun C: Prop => fun H: A -> B => fun H1: A->C => fun H2: A => (conj B C (H H2) (H1 H2)).
Definition triple: forall A: Prop, forall B: Prop, forall C: Prop, A -> B -> C -> (A /\ (B /\ C)) := fun A: Prop => fun B: Prop => fun C: Prop => fun H1: A => fun H2: B => fun H3: C => (conj A (B /\ C) H1 (conj B C H2 H3)).
Definition circ: forall A: Prop, forall B: Prop, (A -> B) -> (B -> ~A) -> ~A := fun A: Prop => fun B: Prop => fun H: A -> B => fun H1: B -> ~A => fun H2: A => (H1 (H H2) H2).
Definition no: forall A: Prop, forall B: Prop, (A -> ~B) -> B -> ~A := fun A: Prop => fun B: Prop => fun H: A -> ~B => fun H1: B => fun H2: A => (H H2 H1).
Definition mpcQ: forall A: Set, forall P: A -> Prop, forall Q: A -> Prop, forall R: A -> Prop, (forall x: A, (P x) -> (Q x)) -> (forall x: A, (P x) -> (R x)) -> (forall x: A, (P x) -> ((Q x) /\ (R x))) := fun A: Set => fun P: A -> Prop => fun Q: A -> Prop => fun R: A -> Prop => fun H: forall x: A, (P x) -> (Q x) => fun H1: forall x: A, (P x) -> (R x) => fun x: A => fun H2: (P x) => (conj (Q x) (R x) (H x H2) (H1 x H2)).
Definition cancel2: forall A: Set, forall P: A -> Prop, forall Q: A -> Prop, (R: A -> Prop) (forall x: A, (P x) -> (Q x) -> (R x)) -> (forall x: A, (Q x)) -> forall x: A, (P x) -> (R x)) fun A: Set => fun P: A -> Prop => fun Q: A -> Prop => fun R: A -> Prop => fun H: forall x: A, (P x) -> (Q x) -> (R x) => fun H1: forall x: A, (Q x) => fun x: A => fun H2: (P x) => (H x H2 (H1 x)).
Definition instan: (forall A: Set, forall P: A -> Prop, (Q: A -> A -> Prop) (forall x: A, (P x) -> forall y: A, (Q x y)) -> (forall x: A, (P x)) -> forall x: A, (Q x x) := fun A: Set => fun P: A -> Prop => fun Q: A -> A -> Prop => fun H: forall x: A, (P x) -> forall y: A, (Q x y) => fun H1: forall x: A, (P x) => fun x: A => (H x (H1 x) x).
Definition mp: forall A: Set, forall a: A, forall P: A -> Prop, forall Q: A -> Prop, (forall x: A, (P x) -> (Q x)) -> (P a) -> (Q a) := fun A: Set => fun a: A => fun P: A -> Prop => fun Q: A -> Prop => fun H: forall x: A, (P x) -> (Q x) => fun H1: (P a) => (H a H1).
Definition mconj: Prop -> Prop -> Prop := fun A: Prop => fun B: Prop => forall P: Prop, (A -> B -> P) -> P.Definire
Definition mconj1: forall A: Prop, forall B: Prop, (mconj A B) -> A := fun A: Prop => fun B: Prop => fun H: (mconj A B) => (H A (fun H1: A => fun H2: B => H1)). Definition mconj2: forall A: Prop, forall B: Prop, (mconj A B) -> B := fun A: Prop => fun B: Prop => fun H: (mconj A B) => (H B (fun H1: A => fun H2: B => H2)). Definition mconj3: forall A: Prop, forall B: Prop, A -> B -> (mconj A B) := fun A: Prop => fun B: Prop => fun H1: A => fun H2: B => (fun P: Prop => fun H3: A -> B -> P => (H3 H1 H2)). Definition mconj4: forall A: Prop, forall B: Prop, (mconj A B) -> (mconj B A) := fun A: Prop => fun B: Prop => fun H: (mconj A B) => (mconj3 B A (mconj2 A B H) (mconj1 A B H)).
Definition mdisj: Prop -> Prop -> Prop := fun A: Prop => fun B: Prop => forall P: Prop, (A -> P) -> (B -> P) -> P.Definire
Definition mdisj1: forall A: Prop, forall B: Prop, A -> (mdisj A B) := fun A: Prop => fun B: Prop => fun H: A => fun P: Prop => fun H1: A -> P => fun H2: B -> P => (H1 H). Definition mdisj2: forall A: Prop, forall B: Prop, B -> (mdisj A B) := fun A: Prop => fun B: Prop => fun H: B => fun P: Prop => fun H1: A -> P => fun H2: B -> P => (H2 H). Definition mdisj3: forall A: Prop, forall B: Prop, forall C: Prop, (mdisj A B) -> (A -> C) -> (B -> C) -> C := fun A: Prop => fun B: Prop => fun C: Prop => fun H: (mdisj A B) => fun H1: A -> C => fun H2: B -> C => (H C H1 H2). Definition mdisj4: forall A: Prop, forall B: Prop, (mdisj A B) -> (mdisj B A) := fun A: Prop => fun B: Prop => fun H: (mdisj A B) => (mdisj3 A B (mdisj B A) H (fun H1: A => (mdisj2 B A H1)) (fun H2: B => (mdisj1 B A H2))).
Definition mfalse: Prop := forall P: Prop, P. Definition mneg: Prop -> Prop := fun A: Prop => A -> mfalse.Definire
Definition mfalse1: forall A: Prop, mfalse -> A := fun A: Prop => fun H: mfalse => (H A). Definition mfalse2: forall A: Prop, A -> (mneg A) -> mfalse := fun A: Prop => fun H: A => fun H1: (mneg A) => (H1 H).
forall P: btree->Prop, (forall n: nat, (P (Leaf n))) -> (forall b1: btree, forall b2: btree, (P b1) -> (P b2) -> (P (Node b1 b2))) -> (forall b: btree, (P b))
forall P: bin->Prop, (P end) -> (forall b: bin, (P b) -> (P (one b))) -> (forall b: bin, (P b) -> (P (zero b))) -> (forall b: bin, (P b))
forall P: nat->nat->nat->Prop, (forall n: nat, (P n n n)) -> (forall n: nat, forall m: nat, forall p: nat, (between n m p) -> (P n m p) -> (P n (S m) (S p))) -> (forall n: nat, forall m: nat, forall p: nat, (between n m p) -> (P n m p) -> (P n m (S p))) -> forall n: nat, forall m: nat, forall p: nat, (between n m p) -> (P n m p)
(* inserimento di un elemento a dentro una lista ordinata L *) Fixpoint insert (a: A) (L: list) {struct L}: list := match L with nil => (cons a nil) | (cons b L1) => match (f_le a b) with true => (cons a L) | false => (cons b (insert a L1)) end end. Fixpoint isort (L: list) {struct L}: list := match L with nil => nil | (cons a L1) => (insert a (isort L1)) end.
Inductive Ordered_list: list -> Prop := Ordered_nil : (Ordered_list nil) | Ordered_single: forall a: A, (Ordered_list (cons a nil)) | Ordered_top : forall a: A, forall b: A, forall L: list, (le a b) -> (Ordered_list (cons b L)) -> (Ordered_list (cons a (cons b L))) .
J43
Scrivere in Coq il predicato
Permutation che esprime che una lista contiene gli stessi elementi
con la stessa molteplicità di un'altra: per esempio, [1;1;2]
ha gli stessi elementi di [1;2;1] ma ha un 1 in piú
di [1;2].
(* ogni permutazione e' una sequenza di trasposizioni *) Inductive Permutation: list -> list -> Prop := Is_perm_nil : (Permutation nil nil) | Is_perm_skip : forall a: A, forall L1: list, forall L2: list, (Permutation L2 L1) -> (Permutation (cons a L2) (cons a L1)) | Is_perm_swap : forall a: A, forall b: A, (L: list) (Permutation (cons a (cons b L)) (cons b (cons a L))) | Is_perm_trans: forall L1: list, forall L2: list, forall L3: list, (Permutation L1 L2) -> (Permutation L2 L3) -> (Permutation L1 L3).
J41
Scrivere in Coq il teorema che esprime che l'algoritmo isort
è corretto.
Theorem isort_correct: forall L: list, (Ordered_list (isort L)) /\ (Permutation L (isort L)).
Theorem trivial: forall A: Prop, A -> A. intro A. intro H. exact H. Qed.
Theorem or_commutative: forall A: Prop, forall B: Prop, A \/ B -> B \/ A. intro A. intro B. intro H. case H. intro H1. right. exact H1. intro H1. left. exact H1. Qed.
Theorem mp: forall A: Prop, forall B: Prop, A -> (A -> B) -> B. intro A. intro B. intro H. intro H1. apply H1. exact H. Qed.
Theorem S: forall A: Prop, forall B: Prop, forall C: Prop, (A -> B -> C) -> (A -> B) -> A -> C. intro A. intro B. intro C. intro H'. intro H'0. intro H'1. apply H'. exact H'1. apply H'0. exact H'1. Qed.
Theorem Praeclarum: forall x: Prop, forall y: Prop, forall z: Prop, forall t: Prop, (x -> z) /\ (y -> t) -> x /\ y -> z /\ t. intro x. intro y. intro z. intro t. intro h. case h. intro h1. intro h2. intro h0. case h0. intro h3. intro h4. split. apply h1. exact h3. apply h2. exact h4. Qed.
Theorem resol: forall p: Type -> Prop, forall q: Type -> Prop, forall a: Type, (p a) -> (forall x: Type, (p x) -> (q x)) -> (q a). intro p. intro q. intro a. intro h. intro h1. apply h1. exact h. Qed.
Theorem S: forall A: Set, forall R: A -> A -> Prop, (forall x: A, forall y: A, forall z: A, (R x y) /\ (R y z) -> (R x z)) -> (forall x: A, forall y: A, (R x y) -> (R y x)) -> forall x: A, (exists y: A, (R x y)) -> (R x x). intro A. intro R. intro Rtrans. intro Rsym. intro x. intro h2. case h2. intro y. intro R0. apply (Rtrans x y). split. exact R0. apply Rsym. exact R0. Qed.
Theorem not_not: forall a: Prop, a -> ~ (~ a). intro a. intro h. red. intro h1. case h1. exact h. Qed.
Theorem mini_cases: forall x: Prop, forall y: Prop, (x \/ ~ y) /\ y -> x. intro x. intro y. intro h. case h. intro h1. intro h2. case h1. intro h3. exact h3. intro h3. case h3. exact h2. Qed.
Theorem not_quite_classic: forall a: Prop, ~ (~ (a \/ ~ a)). intro a. red. intro h. case h. right. red. intro h1. case h. left. exact h1. Qed.