Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
(* Exercise 1 *) (* Define an inductive type for the months in the gregorian calendar *) (*(the French civil calendar) *) Inductive month : Set := |January : month |February : month |March : month |April : month |May : month |June : month |July : month |August : month |September : month |October : month |November : month |December : month. (* Define an inductive type for the four seasons *) Inductive season : Set := |Autumn : season |Winter : season |Spring : season |Summer : season. (* What is the inductive principle generated in each case ?*) Check month_ind. Check season_ind. (* Define a function mapping each month to the season that contains *) (* most of its days, using pattern matching *) Definition season_of_month (m : month) := match m with |January => Winter |February => Winter |March => Winter |April => Spring |May => Spring |June => Spring |July => Summer |August => Summer |September => Summer |October => Autumn |November => Autumn |December => Autumn end. (* Exercise 2 *) (* Define the boolean functions bool_xor, bool_and, bool_eq of type *) (*bool -> bool -> bool, and the function bool_not of type bool -> bool *) Definition bool_not (b:bool) : bool := if b then false else true. Definition bool_xor (b b':bool) : bool := if b then bool_not b' else b'. Definition bool_and (b b':bool) : bool := if b then b' else false. Definition bool_or (b b':bool) := if b then true else b'. Definition bool_eq (b b':bool) := if b then b' else bool_not b'. (* prove the following theorems:*) Lemma bool_xor_not_eq : forall b1 b2 : bool, bool_xor b1 b2 = bool_not (bool_eq b1 b2). Proof. intros b1 b2; case b1; case b2; simpl; trivial. Qed. Lemma bool_not_and : forall b1 b2 : bool, bool_not (bool_and b1 b2) = bool_or (bool_not b1) (bool_not b2). Proof. intros b1 b2; case b1; case b2; simpl; trivial. Qed. Lemma bool_not_not : forall b : bool, bool_not (bool_not b) = b. Proof. intro b; case b; simpl; trivial. Qed. Lemma bool_or_not : forall b : bool, bool_or b (bool_not b) = true. Proof. intro b; case b; simpl; trivial. Qed. Lemma bool_id_eq : forall b1 b2 : bool, b1 = b2 -> bool_eq b1 b2 = true. Proof. intros b1 b2 H; rewrite H; case b2; trivial. Qed. Lemma bool_not_or : forall b1 b2 : bool, bool_not (bool_or b1 b2) = bool_and (bool_not b1) (bool_not b2). Proof. intros b1 b2; case b1; case b2; simpl; trivial. Qed. Lemma bool_or_and : forall b1 b2 b3 : bool, bool_or (bool_and b1 b3) (bool_and b2 b3) = bool_and (bool_or b1 b2) b3. Proof. intros b1 b2 b3; case b1; case b2; case b3; simpl; trivial. Qed. (** New recursive types **) (* Define an inductive type formula : Type that represents the *) (*abstract language of propositional logic without variables: L = L /\ L | L \/ L | ~L | L_true | L_false *) Inductive formula : Type := |L_true : formula |L_false : formula |L_and : formula -> formula -> formula |L_or : formula -> formula -> formula |L_neg : formula -> formula. (* Define a function formula_holds of type (formula -> Prop computing the *) (* Coq formula corresponding to an element of type formula *) Fixpoint formula_holds (f : formula) : Prop := match f with |L_true => True |L_false => False |L_and f1 f2 => (formula_holds f1) /\ (formula_holds f2) |L_or f1 f2 => (formula_holds f1) \/ (formula_holds f2) |L_neg f => ~(formula_holds f) end. (* Define a function isT_formula of type (formula -> bool) computing *) (* the intended truth value of (f : formula) *) Fixpoint isT_formula (f : formula) : bool := match f with |L_true => true |L_false => false |L_and f1 f2 => andb (isT_formula f1) (isT_formula f2) |L_or f1 f2 => orb (isT_formula f1) (isT_formula f2) |L_neg f => negb (isT_formula f) end. (* prove that is (idT_formula f) evaluates to true, then its *) (*corresponding Coq formula holds ie.:*) Require Import Bool. Lemma isT_formula_correct : forall f : formula, isT_formula f = true <-> formula_holds f. Proof. induction f; simpl; split; trivial. (* False *) discriminate. intro h; elim h. (* And *) case_eq (isT_formula f1); intro h1; case_eq (isT_formula f2); intro h2; try discriminate 1. split; [apply IHf1 | apply IHf2]; trivial. destruct IHf1 as [IHf1_1 IHf1_2]. destruct IHf2 as [IHf2_1 IHf2_2]. destruct 1. rewrite IHf1_2; trivial. rewrite IHf2_2; trivial. (* Or *) case_eq (isT_formula f1); intro h1; case_eq (isT_formula f2); intro h2; try discriminate 1. left; apply IHf1; trivial. left; apply IHf1; trivial. right; apply IHf2; trivial. intro h. destruct IHf1 as [IHf1_1 IHf1_2]. destruct IHf2 as [IHf2_1 IHf2_2]. destruct h as [h1 | h2]. rewrite IHf1_2; trivial. rewrite IHf2_2; trivial. SearchAbout orb. rewrite orb_true_r; trivial. (* False *) destruct IHf as [IHf_1 IHf_2]. case_eq (isT_formula f). discriminate 2. intros h1 _ h3. generalize h1. rewrite IHf_2; trivial. discriminate 1. destruct IHf as [IHf_1 IHf_2]. case_eq (isT_formula f); trivial. intros h1 h2. absurd (formula_holds f); trivial. apply IHf_1. trivial. Qed. (* Exercise 3 *) (* We use the inductive type defined in the lecture:*) Inductive natBinTree : Set := | Leaf : nat -> natBinTree | Node : nat -> natBinTree -> natBinTree -> natBinTree. (* Define a function which sums all the values present in the tree. *) Fixpoint sum_natBinTree (t : natBinTree) := match t with |Leaf n => n |Node n t1 t2 => n + (sum_natBinTree t1) + (sum_natBinTree t2) end. (* Define a function is_zero_present : natBinTree -> bool, which tests if the value 0 is present in the tree. *) Fixpoint is_zero_present (t : natBinTree) := match t with |Leaf n => match n with |0 => true |_ => false end |Node n t1 t2 => match n with |0 => true |_ => (is_zero_present t1) || (is_zero_present t2) end end. (* Exercise 4 *) (* Define the function split : forall A B : Set, list A * B -> (list A) * (list B) which transforms a list of pairs into a pair of lists and the function combine : forall A B : Set, list A * list B -> list (A * B) which transforms a pair of lists into a list of pairs. Write and prove a theorem relating the two functions. *) Require Import List. Open Scope type_scope. Fixpoint split (A B: Set)(l: list (A * B)) : (list A)*(list B) := match l with |nil => (nil, nil) | (a, b)::l' => (let (l'1, l'2) := split _ _ l' in (a::l'1, b::l'2)) end. Fixpoint combine (A B: Set)(l1 : list A)(l2 :list B) : list (A * B):= match l1,l2 with |nil,nil => nil | (a :: l'1), ( b::l'2) => (a, b) :: (combine _ _ l'1 l'2) | _, _ => nil end. Theorem combine_of_split : forall (A B:Set) (l:list (A*B)), let (l1, l2) := (split _ _ l) in combine _ _ l1 l2 = l. Proof. simple induction l; simpl; auto. intros p l0; case (split A B l0); simpl; auto. case p; simpl; auto. destruct 1; auto. Qed.