mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	New Verilog and Coq sample files added
New Verilog examples and Coq examples for additional training have been added since linguist is currently failing Coq/Verilog recognition tasks (see #201). In case it wasn't obvious, linguist will not currently pass these new, added test cases.
This commit is contained in:
		
							
								
								
									
										707
									
								
								samples/coq/Basics.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										707
									
								
								samples/coq/Basics.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,707 @@ | |||||||
|  | Inductive day : Type := | ||||||
|  | | monday : day | ||||||
|  | | tuesday : day | ||||||
|  | | wednesday : day | ||||||
|  | | thursday : day | ||||||
|  | | friday : day | ||||||
|  | | saturday : day | ||||||
|  | | sunday : day. | ||||||
|  |  | ||||||
|  | Definition next_weekday (d:day) : day := | ||||||
|  |   match d with | ||||||
|  |   | monday => tuesday | ||||||
|  |   | tuesday => wednesday | ||||||
|  |   | wednesday => thursday | ||||||
|  |   | thursday => friday | ||||||
|  |   | friday => monday | ||||||
|  |   | saturday => monday | ||||||
|  |   | sunday => monday | ||||||
|  |   end. | ||||||
|  |  | ||||||
|  | Example test_next_weekday: | ||||||
|  | (next_weekday (next_weekday saturday)) = tuesday. | ||||||
|  |  | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Inductive bool : Type := | ||||||
|  | 	| true : bool | ||||||
|  | 	| false : bool. | ||||||
|  |  | ||||||
|  | Definition negb (b:bool) : bool := | ||||||
|  | 													 match b with | ||||||
|  | 																			 | true => false | ||||||
|  | 																			 | false => true | ||||||
|  | 													 end. | ||||||
|  |  | ||||||
|  | Definition andb (b1:bool) (b2:bool) : bool := | ||||||
|  | 		match b1 with | ||||||
|  | 		 | true => b2 | ||||||
|  | 		 | false => false | ||||||
|  | 	  end. | ||||||
|  |  | ||||||
|  | Definition orb (b1:bool) (b2:bool) : bool := | ||||||
|  | 		match b1 with | ||||||
|  | 		  | true => true | ||||||
|  | 		  | false => b2 | ||||||
|  | 		end. | ||||||
|  |  | ||||||
|  | Example test_orb1: (orb true false) = true. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Example test_orb2: (orb false false) = false. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Example test_orb3: (orb false true) = true. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Example test_orb4: (orb true true) = true. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Definition nandb (b1: bool) (b2:bool) : bool := | ||||||
|  | 	match b1 with | ||||||
|  | 		| true => match b2 with | ||||||
|  | 										| false => true | ||||||
|  | 										| true => false | ||||||
|  | 							end | ||||||
|  | 		| false => true | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_nandb1: (nandb true false) = true. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  | Example test_nandb2: (nandb false false) = true. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  | Example test_nandb3: (nandb false true) = true. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  | Example test_nandb4: (nandb true true) = false. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Definition andb3 (b1: bool) (b2:bool) (b3:bool) : bool := | ||||||
|  | 	match b1 with | ||||||
|  |     | false => false | ||||||
|  | 		| true => match b2 with | ||||||
|  | 								| false => false | ||||||
|  | 								| true => b3 | ||||||
|  | 							end | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_andb31: (andb3 true true true) = true. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  | Example test_andb32: (andb3 false true true) = false. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  | Example test_andb33: (andb3 true false true) = false. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  | Example test_andb34: (andb3 true true false) = false. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Module Playground1. | ||||||
|  |  | ||||||
|  | Inductive nat : Type := | ||||||
|  | 	| O : nat | ||||||
|  | 	| S : nat -> nat. | ||||||
|  |  | ||||||
|  | Definition pred (n : nat) : nat := | ||||||
|  | 	match n with | ||||||
|  | 		| O => O | ||||||
|  | 		| S n' => n' | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Definition minustwo (n : nat) : nat := | ||||||
|  | 	match n with | ||||||
|  | 		| O => O | ||||||
|  | 		| S O => O | ||||||
|  | 		| S (S n') => n' | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint evenb (n : nat) : bool := | ||||||
|  | 	match n with | ||||||
|  | 		| O => true | ||||||
|  | 		| S O => false | ||||||
|  | 		| S (S n') => evenb n' | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Definition oddb (n : nat) : bool := negb (evenb n). | ||||||
|  |  | ||||||
|  | Example test_oddb1: (oddb (S O)) = true. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | Example test_oddb2: (oddb (S (S (S (S O))))) = false. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Fixpoint plus (n : nat) (m : nat) : nat := | ||||||
|  | 	match n with | ||||||
|  | 		| O => m | ||||||
|  | 		| S n' => S (plus n' m) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint mult (n m : nat) : nat := | ||||||
|  | 	match n with | ||||||
|  | 		| O => O | ||||||
|  | 		| S n' => plus m (mult n' m) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint minus (n m : nat) : nat := | ||||||
|  | 	match n, m with | ||||||
|  | 		| O, _ => n | ||||||
|  | 		| S n', O => S n' | ||||||
|  | 		| S n', S m' => minus n' m' | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint exp (base power : nat) : nat := | ||||||
|  | 	match power with | ||||||
|  | 		| O => S O | ||||||
|  | 		| S p => mult base (exp base p) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint factorial (n : nat) : nat := | ||||||
|  | 	match n with | ||||||
|  | 		| O => S O | ||||||
|  | 		| S n' => mult n (factorial n') | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_factorial1: (factorial (S (S (S O)))) = (S (S (S (S (S (S O)))))). | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Notation "x + y" := (plus x y) (at level 50, left associativity) : nat_scope. | ||||||
|  | Notation "x - y" := (minus x y) (at level 50, left associativity) : nat_scope. | ||||||
|  | Notation "x * y" := (mult x y) (at level 40, left associativity) : nat_scope. | ||||||
|  |  | ||||||
|  | Fixpoint beq_nat (n m : nat) : bool := | ||||||
|  | 	match n with | ||||||
|  | 		| O => match m with | ||||||
|  | 						| O => true | ||||||
|  | 						| S m' => false | ||||||
|  | 					 end | ||||||
|  | 		| S n' => match m with | ||||||
|  | 							| O => false | ||||||
|  | 							| S m' => beq_nat n' m' | ||||||
|  | 							end | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint ble_nat (n m : nat) : bool := | ||||||
|  | 	match n with | ||||||
|  | 		| O => true | ||||||
|  | 		| S n' =>  | ||||||
|  | 				match m with | ||||||
|  | 					| O => false | ||||||
|  | 					| S m' => ble_nat n' m' | ||||||
|  | 				end | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_ble_nat1: (ble_nat (S (S O)) (S (S O))) = true. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  | Example test_ble_nat2: (ble_nat (S (S O)) (S (S (S (S O))))) = true. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  | Example test_ble_nat3: (ble_nat (S (S (S (S O)))) (S (S O))) = false. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Definition blt_nat (n m : nat) : bool := | ||||||
|  | 		(andb (negb (beq_nat n m)) (ble_nat n m)). | ||||||
|  |  | ||||||
|  | Example test_blt_nat1: (blt_nat (S (S O)) (S (S O))) = false. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  | Example test_blt_nat3: (blt_nat (S (S (S (S O)))) (S (S O))) = false. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  | Example test_blt_nat2 : (blt_nat (S (S O)) (S (S (S (S O))))) = true. | ||||||
|  | Proof. simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_O_n : forall n : nat, O + n = n. | ||||||
|  | Proof. | ||||||
|  | 	simpl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_O_n' : forall n : nat, O + n = n. | ||||||
|  | Proof. | ||||||
|  | 	reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_O_n'' : forall n : nat, O + n = n. | ||||||
|  | Proof. | ||||||
|  | 	intros n. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_1_1 : forall n : nat, (S O) + n = S n. | ||||||
|  | Proof. | ||||||
|  | 	intros n. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_0_1: forall n : nat, O * n = O. | ||||||
|  | Proof. | ||||||
|  | 	intros n. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_id_example : forall n m:nat, | ||||||
|  | 	n = m -> n + n = m + m. | ||||||
|  | Proof. | ||||||
|  | 	intros n m. | ||||||
|  | 	intros H. | ||||||
|  | 	rewrite -> H. | ||||||
|  | 	reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_id_exercise : forall n m o: nat, | ||||||
|  | 	n = m -> m = o -> n + m = m + o. | ||||||
|  | Proof. | ||||||
|  | 	intros n m o. | ||||||
|  | 	intros H. | ||||||
|  | 	intros H'. | ||||||
|  | 	rewrite -> H. | ||||||
|  | 	rewrite <- H'. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_0_plus : forall n m : nat, | ||||||
|  | 				(O + n) * m = n * m. | ||||||
|  | Proof. | ||||||
|  | 	intros n m. | ||||||
|  | 	rewrite -> plus_O_n. | ||||||
|  | 	reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_1_plus : forall n m: nat, | ||||||
|  | 	((S O) + n) * m = m + (n * m). | ||||||
|  | Proof. | ||||||
|  | 	intros n m. | ||||||
|  | 	rewrite -> plus_1_1. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_1 : forall n : nat, | ||||||
|  | 				n * (S O) = n. | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	induction n as [| n']. | ||||||
|  | 	reflexivity. | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite -> IHn'. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_1_neq_0 : forall n : nat, | ||||||
|  | 				beq_nat (n + (S O)) O = false. | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	destruct n as [| n']. | ||||||
|  | 	reflexivity. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem zero_nbeq_plus_1 : forall n : nat, | ||||||
|  | 				beq_nat O (n + (S O)) = false. | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	destruct n. | ||||||
|  | 	reflexivity. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Require String. Open Scope string_scope. | ||||||
|  |  | ||||||
|  | Ltac move_to_top x := | ||||||
|  | match reverse goal with | ||||||
|  | | H : _ |- _ => try move x after H | ||||||
|  | end. | ||||||
|  |  | ||||||
|  | Tactic Notation "assert_eq" ident(x) constr(v) := | ||||||
|  | 	let H := fresh in | ||||||
|  | 	assert (x = v) as H by reflexivity; | ||||||
|  | 	clear H. | ||||||
|  |  | ||||||
|  | 	Tactic Notation "Case_aux" ident(x) constr(name) := | ||||||
|  | 		first [ | ||||||
|  | 		set (x := name); move_to_top x | ||||||
|  | 		| assert_eq x name; move_to_top x | ||||||
|  | 		| fail 1 "because we are working on a different case" ]. | ||||||
|  |  | ||||||
|  | 		Ltac Case name := Case_aux Case name. | ||||||
|  | 		Ltac SCase name := Case_aux SCase name. | ||||||
|  | 		Ltac SSCase name := Case_aux SSCase name. | ||||||
|  | 		Ltac SSSCase name := Case_aux SSSCase name. | ||||||
|  | 		Ltac SSSSCase name := Case_aux SSSSCase name. | ||||||
|  | 		Ltac SSSSSCase name := Case_aux SSSSSCase name. | ||||||
|  | 		Ltac SSSSSSCase name := Case_aux SSSSSSCase name. | ||||||
|  | 		Ltac SSSSSSSCase name := Case_aux SSSSSSSCase name. | ||||||
|  |  | ||||||
|  | Theorem andb_true_elim1 : forall b c : bool, | ||||||
|  | 				andb b c = true -> b = true. | ||||||
|  | Proof. | ||||||
|  | 	intros b c H. | ||||||
|  | 	destruct b. | ||||||
|  | 	Case "b = true". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "b = false". | ||||||
|  | 		rewrite <- H. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_0_r : forall n : nat, n + O = n. | ||||||
|  | Proof. | ||||||
|  | 	intros n. induction n as [| n']. | ||||||
|  | 	Case "n = 0". reflexivity. | ||||||
|  | 	Case "n = S n'". simpl. rewrite -> IHn'. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem minus_diag : forall n, | ||||||
|  | 				minus n n = O. | ||||||
|  | Proof. | ||||||
|  | 	intros n. induction n as [| n']. | ||||||
|  | 	Case "n = 0". | ||||||
|  | 		simpl. reflexivity. | ||||||
|  | 	Case "n = S n'". | ||||||
|  | 		simpl. rewrite -> IHn'. reflexivity. Qed. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Theorem mult_0_r : forall n:nat, | ||||||
|  | 				n * O = O. | ||||||
|  | Proof. | ||||||
|  | 	intros n. induction n as [| n']. | ||||||
|  | 	Case "n = 0". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "n = S n'". | ||||||
|  | 		simpl. rewrite -> IHn'. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_n_Sm : forall n m : nat, | ||||||
|  | 				S (n + m) = n + (S m). | ||||||
|  | Proof. | ||||||
|  | 	intros n m. induction n as [| n']. | ||||||
|  | 	Case "n = 0". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "n = S n'". | ||||||
|  | 		simpl. rewrite -> IHn'. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_assoc : forall n m p : nat, | ||||||
|  | 					n + (m + p) = (n + m) + p. | ||||||
|  | Proof. | ||||||
|  | 	intros n m p. | ||||||
|  | 	induction n as [| n']. | ||||||
|  | 	reflexivity. | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite -> IHn'. | ||||||
|  | 	reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_distr : forall n m: nat, S (n + m) = n + (S m). | ||||||
|  | Proof. | ||||||
|  | 	intros n m.  induction n as [| n']. | ||||||
|  | 	Case "n = 0". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "n = S n'". | ||||||
|  | 		simpl. rewrite -> IHn'. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_distr : forall n m: nat, n * ((S O) + m) = n * (S m). | ||||||
|  | Proof. | ||||||
|  | 	intros n m. | ||||||
|  | 	induction n as [| n']. | ||||||
|  | 	reflexivity. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_comm : forall n m : nat, | ||||||
|  | 	n + m = m + n. | ||||||
|  | Proof. | ||||||
|  | 	intros n m. | ||||||
|  | 	induction n as [| n']. | ||||||
|  | 	Case "n = 0". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> plus_0_r. | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "n = S n'". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> IHn'. | ||||||
|  | 		rewrite -> plus_distr. | ||||||
|  | 		reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Fixpoint double (n:nat) := | ||||||
|  | 	match n with | ||||||
|  | 		| O => O | ||||||
|  | 		| S n' => S (S (double n')) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Lemma double_plus : forall n, double n = n + n. | ||||||
|  | Proof. | ||||||
|  | 	intros n. induction n as [| n']. | ||||||
|  | 	Case "n = 0". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "n = S n'". | ||||||
|  | 		simpl. rewrite -> IHn'. | ||||||
|  | 		rewrite -> plus_distr. reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem beq_nat_refl : forall n : nat, | ||||||
|  | 	true = beq_nat n n. | ||||||
|  | Proof. | ||||||
|  | 	intros n. induction n as [| n']. | ||||||
|  | 	Case "n = 0". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "n = S n". | ||||||
|  | 		simpl. rewrite <- IHn'. | ||||||
|  | 		reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_rearrange: forall n m p q : nat, | ||||||
|  | 				(n + m) + (p + q) = (m + n) + (p + q). | ||||||
|  | Proof. | ||||||
|  | 	intros n m p q. | ||||||
|  | 	assert(H: n + m = m + n). | ||||||
|  | 		Case "Proof by assertion". | ||||||
|  | 		rewrite -> plus_comm. reflexivity. | ||||||
|  | 	rewrite -> H. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_swap : forall n m p: nat, | ||||||
|  | 				n + (m + p) = m + (n + p). | ||||||
|  | Proof. | ||||||
|  | 	intros n m p. | ||||||
|  | 	rewrite -> plus_assoc. | ||||||
|  | 	assert(H: m + (n + p) = (m + n) + p). | ||||||
|  | 	rewrite -> plus_assoc. | ||||||
|  | 	reflexivity. | ||||||
|  | 	rewrite -> H. | ||||||
|  | 	assert(H2: m + n = n + m). | ||||||
|  | 	rewrite -> plus_comm. | ||||||
|  | 	reflexivity. | ||||||
|  | 	rewrite -> H2. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_swap' : forall n m p: nat, | ||||||
|  | 				n + (m + p) = m + (n + p). | ||||||
|  | Proof. | ||||||
|  | 	intros n m p. | ||||||
|  | 	rewrite -> plus_assoc. | ||||||
|  | 	assert(H: m + (n + p) = (m + n) + p). | ||||||
|  | 	rewrite -> plus_assoc. | ||||||
|  | 	reflexivity. | ||||||
|  | 	rewrite -> H. | ||||||
|  | 	replace (m + n) with (n + m). | ||||||
|  | 	rewrite -> plus_comm. | ||||||
|  | 	reflexivity. | ||||||
|  | 	rewrite -> plus_comm. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_1_distr: forall m n: nat, | ||||||
|  | 				n * ((S O) + m) = n * (S O) + n * m. | ||||||
|  | Proof. | ||||||
|  | 	intros n m. | ||||||
|  | 	rewrite -> mult_1. | ||||||
|  | 	rewrite -> plus_1_1. | ||||||
|  | 	simpl. | ||||||
|  | 	induction m as [|m']. | ||||||
|  | 	simpl. | ||||||
|  | 	reflexivity. | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite -> plus_swap. | ||||||
|  | 	rewrite <- IHm'. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_comm: forall m n : nat, | ||||||
|  | 				m * n = n * m. | ||||||
|  | Proof. | ||||||
|  | 	intros m n. | ||||||
|  | 	induction n as [| n']. | ||||||
|  | 	Case "n = 0". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> mult_0_r. | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "n = S n'". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite <- mult_distr. | ||||||
|  | 		rewrite -> mult_1_distr. | ||||||
|  | 		rewrite -> mult_1. | ||||||
|  | 		rewrite -> IHn'. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem evenb_next : forall n : nat, | ||||||
|  | 				evenb n = evenb (S (S n)). | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | Admitted. | ||||||
|  |  | ||||||
|  | Theorem negb_negb : forall n : bool, | ||||||
|  | 				n = negb (negb n). | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	destruct n. | ||||||
|  | 	reflexivity. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem evenb_n_oddb_Sn : forall n : nat, | ||||||
|  | 				evenb n = negb (evenb (S n)). | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	induction n as [|n']. | ||||||
|  | 	reflexivity. | ||||||
|  | 	assert(H: evenb n' = evenb (S (S n'))). | ||||||
|  | 	reflexivity. | ||||||
|  | 	rewrite <- H. | ||||||
|  | 	rewrite -> IHn'. | ||||||
|  | 	rewrite <- negb_negb. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | (*Fixpoint bad (n : nat) : bool := | ||||||
|  | 	match n with | ||||||
|  | 		| O => true | ||||||
|  | 		| S O => bad (S n) | ||||||
|  | 		| S (S n') => bad n' | ||||||
|  | 	end.*) | ||||||
|  |  | ||||||
|  | Theorem ble_nat_refl : forall n:nat, | ||||||
|  | 				true = ble_nat n n. | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	induction n as [|n']. | ||||||
|  | 	Case "n = 0". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "n = S n". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite <- IHn'. | ||||||
|  | 		reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem zero_nbeq_S : forall n: nat, | ||||||
|  | 				beq_nat O (S n) = false. | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem andb_false_r : forall b : bool, | ||||||
|  | 				andb b false = false. | ||||||
|  | Proof. | ||||||
|  | 	intros b. | ||||||
|  | 	destruct b. | ||||||
|  | 	reflexivity. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_ble_compat_1 : forall n m p : nat, | ||||||
|  | 				ble_nat n m = true -> ble_nat (p + n) (p + m) = true. | ||||||
|  | Proof. | ||||||
|  | 	intros n m p. | ||||||
|  | 	intros H. | ||||||
|  | 	induction p. | ||||||
|  | 	Case "p = 0". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> H. | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "p = S p'". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> IHp. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem S_nbeq_0 : forall n:nat, | ||||||
|  | 				beq_nat (S n) O = false. | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_1_1 : forall n:nat, (S O) * n = n. | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite -> plus_0_r. | ||||||
|  | 	reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem all3_spec : forall b c : bool, | ||||||
|  | 	orb (andb b c) | ||||||
|  | 			(orb (negb b) | ||||||
|  | 			 		 (negb c)) | ||||||
|  | 	= true. | ||||||
|  | Proof. | ||||||
|  | 	intros b c. | ||||||
|  | 	destruct b. | ||||||
|  | 	destruct c. | ||||||
|  | 	reflexivity. | ||||||
|  | 	reflexivity. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Lemma mult_plus_1 : forall n m : nat, | ||||||
|  | 			S(m + n) = m + (S n). | ||||||
|  | Proof. | ||||||
|  | 	intros n m. | ||||||
|  | 	induction m. | ||||||
|  | 	reflexivity. | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite -> IHm. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_mult : forall n m : nat, | ||||||
|  | 	n * (S m) = n * m + n. | ||||||
|  | Proof. | ||||||
|  | 	intros n m. | ||||||
|  | 	induction n. | ||||||
|  | 	reflexivity. | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite -> IHn. | ||||||
|  | 	rewrite -> plus_assoc. | ||||||
|  | 	rewrite -> mult_plus_1. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_plus_distr_r : forall n m p:nat, | ||||||
|  | 				(n + m) * p = (n * p) + (m * p). | ||||||
|  | Proof. | ||||||
|  | 	intros n m p. | ||||||
|  | 	induction p. | ||||||
|  | 	rewrite -> mult_0_r. | ||||||
|  | 	rewrite -> mult_0_r. | ||||||
|  | 	rewrite -> mult_0_r. | ||||||
|  | 	reflexivity. | ||||||
|  | 	rewrite -> mult_mult. | ||||||
|  | 	rewrite -> mult_mult. | ||||||
|  | 	rewrite -> mult_mult. | ||||||
|  | 	rewrite -> IHp. | ||||||
|  | 	assert(H1: ((n * p) + n) + (m * p + m) = (n * p) + (n + (m * p + m))). | ||||||
|  | 	rewrite <- plus_assoc. | ||||||
|  | 	reflexivity. | ||||||
|  | 	rewrite -> H1. | ||||||
|  | 	assert(H2: (n + (m * p + m)) = (m * p + (n + m))). | ||||||
|  | 	rewrite -> plus_swap. | ||||||
|  | 	reflexivity. | ||||||
|  | 	rewrite -> H2. | ||||||
|  | 	assert(H3: (n * p) + (m * p + (n + m)) = ((n * p ) + (m * p)) + (n + m)). | ||||||
|  | 	rewrite -> plus_assoc. | ||||||
|  | 	reflexivity. | ||||||
|  | 	rewrite -> H3. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem mult_assoc : forall n m p : nat, | ||||||
|  | 				n * (m * p) = (n * m) * p. | ||||||
|  | Proof. | ||||||
|  | 	intros n m p. | ||||||
|  | 	induction n. | ||||||
|  | 	simpl. | ||||||
|  | 	reflexivity. | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite -> mult_plus_distr_r. | ||||||
|  | 	rewrite -> IHn. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Inductive bin : Type := | ||||||
|  | 	| BO : bin | ||||||
|  | 	| D : bin -> bin | ||||||
|  | 	| M : bin -> bin. | ||||||
|  |  | ||||||
|  | Fixpoint incbin (n : bin) : bin := | ||||||
|  | 	match n with | ||||||
|  | 		| BO => M (BO) | ||||||
|  | 		| D n' => M n' | ||||||
|  | 		| M n' => D (incbin n') | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint bin2un (n : bin) : nat := | ||||||
|  | 	match n with | ||||||
|  | 		| BO => O | ||||||
|  | 		| D n' => double (bin2un n') | ||||||
|  | 		| M n' => S (double (bin2un n')) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Theorem bin_comm : forall n : bin, | ||||||
|  | 				bin2un(incbin n) = S (bin2un n). | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	induction n. | ||||||
|  | 		reflexivity. | ||||||
|  | 		reflexivity. | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> IHn. | ||||||
|  | 		reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | End Playground1. | ||||||
							
								
								
									
										300
									
								
								samples/coq/Heap.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										300
									
								
								samples/coq/Heap.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,300 @@ | |||||||
|  | (************************************************************************) | ||||||
|  | (*  v      *   The Coq Proof Assistant  /  The Coq Development Team     *) | ||||||
|  | (* <O___,, *   INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010     *) | ||||||
|  | (*   \VV/  **************************************************************) | ||||||
|  | (*    //   *      This file is distributed under the terms of the       *) | ||||||
|  | (*         *       GNU Lesser General Public License Version 2.1        *) | ||||||
|  | (************************************************************************) | ||||||
|  |  | ||||||
|  | (** This file is deprecated, for a tree on list, use [Mergesort.v]. *) | ||||||
|  |  | ||||||
|  | (** A development of Treesort on Heap trees. It has an average | ||||||
|  |     complexity of O(n.log n) but of O(n²) in the worst case (e.g. if | ||||||
|  |     the list is already sorted) *) | ||||||
|  |  | ||||||
|  | (* G. Huet 1-9-95 uses Multiset *) | ||||||
|  |  | ||||||
|  | Require Import List Multiset PermutSetoid Relations Sorting. | ||||||
|  |  | ||||||
|  | Section defs. | ||||||
|  |  | ||||||
|  |   (** * Trees and heap trees *) | ||||||
|  |  | ||||||
|  |   (** ** Definition of trees over an ordered set *) | ||||||
|  |  | ||||||
|  |   Variable A : Type. | ||||||
|  |   Variable leA : relation A. | ||||||
|  |   Variable eqA : relation A. | ||||||
|  |  | ||||||
|  |   Let gtA (x y:A) := ~ leA x y. | ||||||
|  |  | ||||||
|  |   Hypothesis leA_dec : forall x y:A, {leA x y} + {leA y x}. | ||||||
|  |   Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}. | ||||||
|  |   Hypothesis leA_refl : forall x y:A, eqA x y -> leA x y. | ||||||
|  |   Hypothesis leA_trans : forall x y z:A, leA x y -> leA y z -> leA x z. | ||||||
|  |   Hypothesis leA_antisym : forall x y:A, leA x y -> leA y x -> eqA x y. | ||||||
|  |  | ||||||
|  |   Hint Resolve leA_refl. | ||||||
|  |   Hint Immediate eqA_dec leA_dec leA_antisym. | ||||||
|  |  | ||||||
|  |   Let emptyBag := EmptyBag A. | ||||||
|  |   Let singletonBag := SingletonBag _ eqA_dec. | ||||||
|  |  | ||||||
|  |   Inductive Tree := | ||||||
|  |     | Tree_Leaf : Tree | ||||||
|  |     | Tree_Node : A -> Tree -> Tree -> Tree. | ||||||
|  |  | ||||||
|  |   (** [a] is lower than a Tree [T] if [T] is a Leaf | ||||||
|  |       or [T] is a Node holding [b>a] *) | ||||||
|  |  | ||||||
|  |   Definition leA_Tree (a:A) (t:Tree) := | ||||||
|  |     match t with | ||||||
|  |       | Tree_Leaf => True | ||||||
|  |       | Tree_Node b T1 T2 => leA a b | ||||||
|  |     end. | ||||||
|  |  | ||||||
|  |   Lemma leA_Tree_Leaf : forall a:A, leA_Tree a Tree_Leaf. | ||||||
|  |   Proof. | ||||||
|  |     simpl; auto with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  |   Lemma leA_Tree_Node : | ||||||
|  |     forall (a b:A) (G D:Tree), leA a b -> leA_Tree a (Tree_Node b G D). | ||||||
|  |   Proof. | ||||||
|  |     simpl; auto with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   (** ** The heap property *) | ||||||
|  |  | ||||||
|  |   Inductive is_heap : Tree -> Prop := | ||||||
|  |     | nil_is_heap : is_heap Tree_Leaf | ||||||
|  |     | node_is_heap : | ||||||
|  |       forall (a:A) (T1 T2:Tree), | ||||||
|  |         leA_Tree a T1 -> | ||||||
|  |         leA_Tree a T2 -> | ||||||
|  |         is_heap T1 -> is_heap T2 -> is_heap (Tree_Node a T1 T2). | ||||||
|  |  | ||||||
|  |   Lemma invert_heap : | ||||||
|  |     forall (a:A) (T1 T2:Tree), | ||||||
|  |       is_heap (Tree_Node a T1 T2) -> | ||||||
|  |       leA_Tree a T1 /\ leA_Tree a T2 /\ is_heap T1 /\ is_heap T2. | ||||||
|  |   Proof. | ||||||
|  |     intros; inversion H; auto with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  |   (* This lemma ought to be generated automatically by the Inversion tools *) | ||||||
|  |   Lemma is_heap_rect : | ||||||
|  |     forall P:Tree -> Type, | ||||||
|  |       P Tree_Leaf -> | ||||||
|  |       (forall (a:A) (T1 T2:Tree), | ||||||
|  | 	leA_Tree a T1 -> | ||||||
|  | 	leA_Tree a T2 -> | ||||||
|  | 	is_heap T1 -> P T1 -> is_heap T2 -> P T2 -> P (Tree_Node a T1 T2)) -> | ||||||
|  |       forall T:Tree, is_heap T -> P T. | ||||||
|  |   Proof. | ||||||
|  |     simple induction T; auto with datatypes. | ||||||
|  |     intros a G PG D PD PN. | ||||||
|  |     elim (invert_heap a G D); auto with datatypes. | ||||||
|  |     intros H1 H2; elim H2; intros H3 H4; elim H4; intros. | ||||||
|  |     apply X0; auto with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  |   (* This lemma ought to be generated automatically by the Inversion tools *) | ||||||
|  |   Lemma is_heap_rec : | ||||||
|  |     forall P:Tree -> Set, | ||||||
|  |       P Tree_Leaf -> | ||||||
|  |       (forall (a:A) (T1 T2:Tree), | ||||||
|  | 	leA_Tree a T1 -> | ||||||
|  | 	leA_Tree a T2 -> | ||||||
|  | 	is_heap T1 -> P T1 -> is_heap T2 -> P T2 -> P (Tree_Node a T1 T2)) -> | ||||||
|  |       forall T:Tree, is_heap T -> P T. | ||||||
|  |   Proof. | ||||||
|  |     simple induction T; auto with datatypes. | ||||||
|  |     intros a G PG D PD PN. | ||||||
|  |     elim (invert_heap a G D); auto with datatypes. | ||||||
|  |     intros H1 H2; elim H2; intros H3 H4; elim H4; intros. | ||||||
|  |     apply X; auto with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  |   Lemma low_trans : | ||||||
|  |     forall (T:Tree) (a b:A), leA a b -> leA_Tree b T -> leA_Tree a T. | ||||||
|  |   Proof. | ||||||
|  |     simple induction T; auto with datatypes. | ||||||
|  |     intros; simpl; apply leA_trans with b; auto with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  |   (** ** Merging two sorted lists *) | ||||||
|  |  | ||||||
|  |   Inductive merge_lem (l1 l2:list A) : Type := | ||||||
|  |     merge_exist : | ||||||
|  |     forall l:list A, | ||||||
|  |       Sorted leA l -> | ||||||
|  |       meq (list_contents _ eqA_dec l) | ||||||
|  |       (munion (list_contents _ eqA_dec l1) (list_contents _ eqA_dec l2)) -> | ||||||
|  |       (forall a, HdRel leA a l1 -> HdRel leA a l2 -> HdRel leA a l) -> | ||||||
|  |       merge_lem l1 l2. | ||||||
|  |   Require Import Morphisms. | ||||||
|  |    | ||||||
|  |   Instance: Equivalence (@meq A). | ||||||
|  |   Proof. constructor; auto with datatypes. red. apply meq_trans. Defined. | ||||||
|  |  | ||||||
|  |   Instance: Proper (@meq A ++> @meq _ ++> @meq _) (@munion A). | ||||||
|  |   Proof. intros x y H x' y' H'. now apply meq_congr. Qed. | ||||||
|  |    | ||||||
|  |   Lemma merge : | ||||||
|  |     forall l1:list A, Sorted leA l1 -> | ||||||
|  |     forall l2:list A, Sorted leA l2 -> merge_lem l1 l2. | ||||||
|  |   Proof. | ||||||
|  |     fix 1; intros; destruct l1. | ||||||
|  |     apply merge_exist with l2; auto with datatypes. | ||||||
|  |     rename l1 into l. | ||||||
|  |     revert l2 H0. fix 1. intros. | ||||||
|  |     destruct l2 as [|a0 l0].  | ||||||
|  |     apply merge_exist with (a :: l); simpl; auto with datatypes.  | ||||||
|  |     elim (leA_dec a a0); intros. | ||||||
|  |  | ||||||
|  |     (* 1 (leA a a0) *) | ||||||
|  |     apply Sorted_inv in H. destruct H. | ||||||
|  |     destruct (merge l H (a0 :: l0) H0). | ||||||
|  |     apply merge_exist with (a :: l1). clear merge merge0. | ||||||
|  |       auto using cons_sort, cons_leA with datatypes. | ||||||
|  |     simpl. rewrite m. now rewrite munion_ass.  | ||||||
|  |     intros. apply cons_leA.  | ||||||
|  |     apply (@HdRel_inv _ leA) with l; trivial with datatypes. | ||||||
|  |  | ||||||
|  |     (* 2 (leA a0 a) *) | ||||||
|  |     apply Sorted_inv in H0. destruct H0. | ||||||
|  |     destruct (merge0 l0 H0). clear merge merge0.   | ||||||
|  |     apply merge_exist with (a0 :: l1);  | ||||||
|  |       auto using cons_sort, cons_leA with datatypes. | ||||||
|  |     simpl; rewrite m. simpl. setoid_rewrite munion_ass at 1. rewrite munion_comm. | ||||||
|  |     repeat rewrite munion_ass. setoid_rewrite munion_comm at 3. reflexivity. | ||||||
|  |     intros. apply cons_leA.  | ||||||
|  |     apply (@HdRel_inv _ leA) with l0; trivial with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  |   (** ** From trees to multisets *) | ||||||
|  |  | ||||||
|  |   (** contents of a tree as a multiset *) | ||||||
|  |  | ||||||
|  |   (** Nota Bene : In what follows the definition of SingletonBag | ||||||
|  |       in not used. Actually, we could just take as postulate: | ||||||
|  |       [Parameter SingletonBag : A->multiset].  *) | ||||||
|  |  | ||||||
|  |   Fixpoint contents (t:Tree) : multiset A := | ||||||
|  |     match t with | ||||||
|  |       | Tree_Leaf => emptyBag | ||||||
|  |       | Tree_Node a t1 t2 => | ||||||
|  | 	munion (contents t1) (munion (contents t2) (singletonBag a)) | ||||||
|  |     end. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   (** equivalence of two trees is equality of corresponding multisets *) | ||||||
|  |   Definition equiv_Tree (t1 t2:Tree) := meq (contents t1) (contents t2). | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   (** * From lists to sorted lists *) | ||||||
|  |  | ||||||
|  |   (** ** Specification of heap insertion *) | ||||||
|  |  | ||||||
|  |   Inductive insert_spec (a:A) (T:Tree) : Type := | ||||||
|  |     insert_exist : | ||||||
|  |     forall T1:Tree, | ||||||
|  |       is_heap T1 -> | ||||||
|  |       meq (contents T1) (munion (contents T) (singletonBag a)) -> | ||||||
|  |       (forall b:A, leA b a -> leA_Tree b T -> leA_Tree b T1) -> | ||||||
|  |       insert_spec a T. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   Lemma insert : forall T:Tree, is_heap T -> forall a:A, insert_spec a T. | ||||||
|  |   Proof. | ||||||
|  |     simple induction 1; intros. | ||||||
|  |     apply insert_exist with (Tree_Node a Tree_Leaf Tree_Leaf); | ||||||
|  |       auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes. | ||||||
|  |     simpl; unfold meq, munion; auto using node_is_heap with datatypes. | ||||||
|  |     elim (leA_dec a a0); intros. | ||||||
|  |     elim (X a0); intros. | ||||||
|  |     apply insert_exist with (Tree_Node a T2 T0); | ||||||
|  |       auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes. | ||||||
|  |     simpl; apply treesort_twist1; trivial with datatypes. | ||||||
|  |     elim (X a); intros T3 HeapT3 ConT3 LeA. | ||||||
|  |     apply insert_exist with (Tree_Node a0 T2 T3); | ||||||
|  |       auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes. | ||||||
|  |     apply node_is_heap; auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes. | ||||||
|  |     apply low_trans with a; auto with datatypes. | ||||||
|  |     apply LeA; auto with datatypes. | ||||||
|  |     apply low_trans with a; auto with datatypes. | ||||||
|  |     simpl; apply treesort_twist2; trivial with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   (** ** Building a heap from a list *) | ||||||
|  |  | ||||||
|  |   Inductive build_heap (l:list A) : Type := | ||||||
|  |     heap_exist : | ||||||
|  |     forall T:Tree, | ||||||
|  |       is_heap T -> | ||||||
|  |       meq (list_contents _ eqA_dec l) (contents T) -> build_heap l. | ||||||
|  |  | ||||||
|  |   Lemma list_to_heap : forall l:list A, build_heap l. | ||||||
|  |   Proof. | ||||||
|  |     simple induction l. | ||||||
|  |     apply (heap_exist nil Tree_Leaf); auto with datatypes. | ||||||
|  |     simpl; unfold meq; exact nil_is_heap. | ||||||
|  |     simple induction 1. | ||||||
|  |     intros T i m; elim (insert T i a). | ||||||
|  |     intros; apply heap_exist with T1; simpl; auto with datatypes. | ||||||
|  |     apply meq_trans with (munion (contents T) (singletonBag a)). | ||||||
|  |     apply meq_trans with (munion (singletonBag a) (contents T)). | ||||||
|  |     apply meq_right; trivial with datatypes. | ||||||
|  |     apply munion_comm. | ||||||
|  |     apply meq_sym; trivial with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   (** ** Building the sorted list *) | ||||||
|  |  | ||||||
|  |   Inductive flat_spec (T:Tree) : Type := | ||||||
|  |     flat_exist : | ||||||
|  |     forall l:list A, | ||||||
|  |       Sorted leA l -> | ||||||
|  |       (forall a:A, leA_Tree a T -> HdRel leA a l) -> | ||||||
|  |       meq (contents T) (list_contents _ eqA_dec l) -> flat_spec T. | ||||||
|  |  | ||||||
|  |   Lemma heap_to_list : forall T:Tree, is_heap T -> flat_spec T. | ||||||
|  |   Proof. | ||||||
|  |     intros T h; elim h; intros. | ||||||
|  |     apply flat_exist with (nil (A:=A)); auto with datatypes. | ||||||
|  |     elim X; intros l1 s1 i1 m1; elim X0; intros l2 s2 i2 m2. | ||||||
|  |     elim (merge _ s1 _ s2); intros. | ||||||
|  |     apply flat_exist with (a :: l); simpl; auto with datatypes. | ||||||
|  |     apply meq_trans with | ||||||
|  |       (munion (list_contents _ eqA_dec l1) | ||||||
|  | 	(munion (list_contents _ eqA_dec l2) (singletonBag a))). | ||||||
|  |     apply meq_congr; auto with datatypes. | ||||||
|  |     apply meq_trans with | ||||||
|  |       (munion (singletonBag a) | ||||||
|  | 	(munion (list_contents _ eqA_dec l1) (list_contents _ eqA_dec l2))). | ||||||
|  |     apply munion_rotate. | ||||||
|  |     apply meq_right; apply meq_sym; trivial with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   (** * Specification of treesort *) | ||||||
|  |  | ||||||
|  |   Theorem treesort : | ||||||
|  |     forall l:list A, | ||||||
|  |     {m : list A | Sorted leA m & permutation _ eqA_dec l m}. | ||||||
|  |   Proof. | ||||||
|  |     intro l; unfold permutation. | ||||||
|  |     elim (list_to_heap l). | ||||||
|  |     intros. | ||||||
|  |     elim (heap_to_list T); auto with datatypes. | ||||||
|  |     intros. | ||||||
|  |     exists l0; auto with datatypes. | ||||||
|  |     apply meq_trans with (contents T); trivial with datatypes. | ||||||
|  |   Qed. | ||||||
|  |  | ||||||
|  | End defs. | ||||||
							
								
								
									
										1558
									
								
								samples/coq/Imp.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1558
									
								
								samples/coq/Imp.v
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										591
									
								
								samples/coq/Lists.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										591
									
								
								samples/coq/Lists.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,591 @@ | |||||||
|  | Require Export Basics. | ||||||
|  | Module NatList. | ||||||
|  | Import Playground1. | ||||||
|  |  | ||||||
|  | Inductive natprod : Type := | ||||||
|  | 	pair : nat -> nat -> natprod. | ||||||
|  |  | ||||||
|  | Definition fst (p : natprod) : nat := | ||||||
|  | 	match p with | ||||||
|  | 		| pair x y => x | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Definition snd (p : natprod) : nat := | ||||||
|  | 	match p with | ||||||
|  | 		| pair x y => y | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Notation "( x , y )" := (pair x y). | ||||||
|  |  | ||||||
|  | Definition swap_pair (p : natprod) : natprod := | ||||||
|  | 	match p with | ||||||
|  | 			| (x, y) => (y, x) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Theorem surjective_pairing' : forall (n m : nat), | ||||||
|  | 	(n, m) = (fst (n, m), snd (n, m)). | ||||||
|  | Proof. | ||||||
|  | 	reflexivity.  Qed. | ||||||
|  |  | ||||||
|  | Theorem surjective_pairing : forall (p : natprod), | ||||||
|  | 	p = (fst p, snd p). | ||||||
|  | Proof. | ||||||
|  | 	intros p. | ||||||
|  | 	destruct p as (n, m). | ||||||
|  | 	simpl. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem snd_fst_is_swap : forall (p : natprod), | ||||||
|  | 	(snd p, fst p) = swap_pair p. | ||||||
|  | Proof. | ||||||
|  | 	intros p. | ||||||
|  | 	destruct p. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem fst_swap_is_snd : forall (p : natprod), | ||||||
|  | 	 fst (swap_pair p) = snd p. | ||||||
|  | Proof. | ||||||
|  | 	intros p. | ||||||
|  | 	destruct p. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Inductive natlist : Type := | ||||||
|  | 	| nil : natlist | ||||||
|  | 	| cons : nat -> natlist -> natlist. | ||||||
|  |  | ||||||
|  | Definition l_123 := cons (S O) (cons (S (S O)) (cons (S (S (S O))) nil)). | ||||||
|  |  | ||||||
|  | Notation "x :: l" := (cons x l) (at level 60, right associativity). | ||||||
|  | Notation "[ ]" := nil. | ||||||
|  | Notation "[]" := nil. | ||||||
|  | Notation "[ x , .. , y ]" := (cons x .. (cons y nil) ..). | ||||||
|  |  | ||||||
|  | Fixpoint repeat (n count : nat) : natlist := | ||||||
|  | 	match count with | ||||||
|  | 		| O => nil | ||||||
|  | 		| S count' => n :: (repeat n count') | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint length (l:natlist) : nat := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => O | ||||||
|  | 		| h :: t => S (length t) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint app (l1 l2 : natlist) : natlist := | ||||||
|  | 	match l1 with | ||||||
|  | 		| nil => l2 | ||||||
|  | 		| h :: t => h :: (app t l2) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Notation "x ++ y" := (app x y) (right associativity, at level 60). | ||||||
|  |  | ||||||
|  | (* | ||||||
|  | Example test_app1: [1,2,3] ++ [4,5] = [1,2,3,4,5]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | Example test_app2: nil ++ [4,5] = [4,5]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | Example test_app3: [1,2,3] ++ [] = [1,2,3]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | *) | ||||||
|  |  | ||||||
|  | Definition head (l : natlist) : nat := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => O | ||||||
|  | 		| h :: t => h | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Definition tl (l : natlist) : natlist := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => nil | ||||||
|  | 		| h :: t => t | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | 			(* | ||||||
|  | Example test_tl: tl [1,2,3] = [2,3]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | *) | ||||||
|  |  | ||||||
|  | Fixpoint nonzeros (l:natlist) : natlist := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => nil | ||||||
|  | 		| O :: r => nonzeros r | ||||||
|  | 		| n :: r => n :: (nonzeros r) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_nonzeros: nonzeros [O,S O,O,S (S O), S (S (S O)),O,O] = [S O,S (S O), S (S (S O))]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Fixpoint oddmembers (l:natlist) : natlist := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => nil | ||||||
|  | 		| n :: r => match (oddb n) with | ||||||
|  | 										| true => n :: (oddmembers r) | ||||||
|  | 										| false => oddmembers r | ||||||
|  | 								end | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_oddmembers: oddmembers [O, S O, O, S (S O), S (S (S O)), O, O] = [S O, S (S (S O))]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Fixpoint countoddmembers (l:natlist) : nat := | ||||||
|  | 		length (oddmembers l). | ||||||
|  |  | ||||||
|  | Example test_countoddmembers2: countoddmembers [O, S (S O), S (S (S (S O)))] = O. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Example test_countoddmembers3: countoddmembers [] = O. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Fixpoint alternate (l1 l2 : natlist) : natlist := | ||||||
|  | 		match l1 with | ||||||
|  | 				| nil => l2 | ||||||
|  | 				| a :: r1 => match l2 with | ||||||
|  | 											| nil => l1 | ||||||
|  | 											| b :: r2 => a :: b :: (alternate r1 r2) | ||||||
|  | 										end | ||||||
|  | 		end. | ||||||
|  |  | ||||||
|  | Example test_alternative1: alternate [S O, S (S O), S (S (S O))] [S (S (S (S O))), S (S (S (S (S O)))), S (S (S (S (S (S O)))))] = | ||||||
|  | 		[S O, S (S (S (S O))), S (S O), S (S (S (S (S O)))), S (S (S O)), S (S (S (S (S (S O)))))]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Definition bag := natlist. | ||||||
|  |  | ||||||
|  | Fixpoint count (v : nat) (s: bag) : nat := | ||||||
|  | 	match s with | ||||||
|  | 		| nil => O | ||||||
|  | 		| v' :: r => match (beq_nat v' v) with | ||||||
|  | 										| true => S (count v r) | ||||||
|  | 										| false => count v r | ||||||
|  | 								 end | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_count1: count (S O) [S O, S (S O), S (S (S O)), S O, S (S (S (S O))), S O] = S (S (S O)). | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Definition sum : bag -> bag -> bag := app. | ||||||
|  |  | ||||||
|  | Example test_sum1: count (S O) (sum [S O, S (S O), S (S (S O))] [S O, S (S (S (S O))), S O]) = S (S (S O)). | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Definition add (v:nat) (s:bag) : bag := v :: s. | ||||||
|  |  | ||||||
|  | Example test_add1: count (S O) (add (S O) [S O, S (S (S (S O))), S O]) = S (S (S O)). | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Definition member (v:nat) (s:bag) : bool := | ||||||
|  | 	ble_nat (S O) (count v s). | ||||||
|  |  | ||||||
|  | Example test_member1: member (S O) [S O, S (S (S (S O))), S O] = true. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Example test_member2: member (S (S O)) [S O, S (S (S (S O))), S O] = false. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Fixpoint remove_one (v:nat) (s:bag) : bag := | ||||||
|  | 	match s with | ||||||
|  | 		| nil => nil | ||||||
|  | 		| v' :: r => match (beq_nat v v') with | ||||||
|  | 									| true => r | ||||||
|  | 									| false => v' :: (remove_one v r) | ||||||
|  | 								 end | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_remove_one1: count (S (S (S (S (S O))))) | ||||||
|  | 																(remove_one (S (S (S (S (S O))))) | ||||||
|  | 																[S (S O), S O, S (S (S (S (S O)))), S (S (S (S O))), S O]) = O. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Fixpoint remove_all (v:nat) (s:bag) : bag := | ||||||
|  | 	match s with | ||||||
|  | 		| nil => nil | ||||||
|  | 		| v' :: r => match (beq_nat v v') with | ||||||
|  | 										| true => remove_all v r | ||||||
|  | 										| false => v' :: (remove_all v r) | ||||||
|  | 								 end | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_remove_all1: count (S (S (S (S (S O))))) | ||||||
|  | 																(remove_all (S (S (S (S (S O))))) | ||||||
|  | 																[S (S O), S O, S (S (S (S (S O)))), S (S (S (S O))), S O]) = O. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Fixpoint subset (s1:bag) (s2:bag) : bool := | ||||||
|  | 		match s1 with | ||||||
|  | 			| nil => true | ||||||
|  | 			| v :: r => andb (member v s2) | ||||||
|  | 											 (subset r (remove_one v s2)) | ||||||
|  | 		end. | ||||||
|  |  | ||||||
|  | Definition test_subset1: subset [S O, S (S O)] [S (S O), S O, S (S (S (S O))), S O] = true. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | Definition test_subset2: subset [S O, S (S O), S (S O)] [S (S O), S O, S (S (S (S O))), S O] = false. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem bag_count_add : forall n t: nat, forall s : bag, | ||||||
|  | 				count n s = t -> count n (add n s) = S t. | ||||||
|  | Proof. | ||||||
|  | 	intros n t s. | ||||||
|  | 	intros H. | ||||||
|  | 	induction s. | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite <- beq_nat_refl. | ||||||
|  | 	rewrite <- H. | ||||||
|  | 	reflexivity. | ||||||
|  | 	rewrite <- H. | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite <- beq_nat_refl. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem nil_app : forall l:natlist, | ||||||
|  | 	[] ++ l = l. | ||||||
|  | Proof. | ||||||
|  | 	reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem tl_length_pred : forall l:natlist, | ||||||
|  | 	pred (length l) = length (tl l). | ||||||
|  | Proof. | ||||||
|  | 	intros l. destruct l as [| n l']. | ||||||
|  | 	Case "l = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l = cons n l'". | ||||||
|  | 		reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem app_ass:forall l1 l2 l3 : natlist, | ||||||
|  | 	(l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3). | ||||||
|  | Proof. | ||||||
|  | 	intros l1 l2 l3. induction l1 as [| n l1']. | ||||||
|  | 	Case "l1 = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l1 = cons n l1'". | ||||||
|  | 		simpl. rewrite -> IHl1'. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem app_length: forall l1 l2 : natlist, | ||||||
|  | 	length (l1 ++ l2) = (length l1) + (length l2). | ||||||
|  | Proof. | ||||||
|  | 	intros l1 l2. induction l1 as [| n l1']. | ||||||
|  | 	Case "l1 = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l1 = cons". | ||||||
|  | 		simpl. rewrite -> IHl1'. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Fixpoint snoc (l:natlist) (v:nat) : natlist := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => [v] | ||||||
|  | 		| h :: t => h :: (snoc t v) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint rev (l:natlist) : natlist := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => nil | ||||||
|  | 		| h :: t => snoc (rev t) h | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_rev1: rev [S O, S (S O), S (S (S O))] = [S (S (S O)), S (S O), S O]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem length_snoc : forall n : nat, forall l : natlist, | ||||||
|  | 	length (snoc l n) = S (length l). | ||||||
|  | Proof. | ||||||
|  | 	intros n l. induction l as [| n' l']. | ||||||
|  | 	Case "l = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l = cons n' l'". | ||||||
|  | 		simpl. rewrite -> IHl'. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem rev_length : forall l : natlist, | ||||||
|  | 	length (rev l) = length l. | ||||||
|  | Proof. | ||||||
|  | 	intros l. induction l as [| n l']. | ||||||
|  | 	Case "l = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l = cons". | ||||||
|  | 		simpl. rewrite -> length_snoc. | ||||||
|  | 		rewrite -> IHl'. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem app_nil_end : forall l :natlist, | ||||||
|  | 	l ++ [] = l. | ||||||
|  | Proof. | ||||||
|  | 	intros l. | ||||||
|  | 	induction l. | ||||||
|  | 	Case "l = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l = cons". | ||||||
|  | 		simpl. rewrite -> IHl. reflexivity. Qed. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Theorem rev_snoc : forall l: natlist, forall n : nat, | ||||||
|  | 	rev (snoc l n) = n :: (rev l). | ||||||
|  | Proof. | ||||||
|  | 	intros l n. | ||||||
|  | 	induction l. | ||||||
|  | 	Case "l = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l = cons". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> IHl. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem rev_involutive : forall l : natlist, | ||||||
|  | 	rev (rev l) = l. | ||||||
|  | Proof. | ||||||
|  | 	intros l. | ||||||
|  | 	induction l. | ||||||
|  | 	Case "l = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l = cons". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> rev_snoc. | ||||||
|  | 		rewrite -> IHl. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem app_ass4 : forall l1 l2 l3 l4 : natlist, | ||||||
|  | 	l1 ++ (l2 ++ (l3 ++ l4)) = ((l1 ++ l2) ++ l3) ++ l4. | ||||||
|  | Proof. | ||||||
|  | 	intros l1 l2 l3 l4. | ||||||
|  | 	rewrite -> app_ass. | ||||||
|  | 	rewrite -> app_ass. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem snoc_append : forall (l : natlist) (n : nat), | ||||||
|  | 	snoc l n = l ++ [n]. | ||||||
|  | Proof. | ||||||
|  | 	intros l n. | ||||||
|  | 	induction l. | ||||||
|  | 	Case "l = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l = cons". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> IHl. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem nonzeros_length : forall l1 l2 : natlist, | ||||||
|  | 	nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2). | ||||||
|  | Proof. | ||||||
|  | 	intros l1 l2. | ||||||
|  | 	induction l1. | ||||||
|  | 	Case "l1 = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l1 = cons". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> IHl1. | ||||||
|  | 		destruct n. | ||||||
|  | 		reflexivity. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem distr_rev : forall l1 l2 : natlist, | ||||||
|  | 	rev (l1 ++ l2) = (rev l2) ++ (rev l1). | ||||||
|  | Proof. | ||||||
|  | 	intros l1 l2. | ||||||
|  | 	induction l1. | ||||||
|  | 	Case "l1 = nil". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> app_nil_end. | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l1 = cons". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> IHl1. | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> snoc_append. | ||||||
|  | 		rewrite -> snoc_append. | ||||||
|  | 		rewrite -> app_ass. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem count_number_nonzero : forall (s : bag), | ||||||
|  | 	ble_nat O (count (S O) (S O :: s)) = true. | ||||||
|  | Proof. | ||||||
|  | 	intros s. | ||||||
|  | 	induction s. | ||||||
|  | 		reflexivity. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem ble_n_Sn : forall n, | ||||||
|  | 	ble_nat n (S n) = true. | ||||||
|  | Proof. | ||||||
|  | 	intros n. induction n as [| n']. | ||||||
|  | 	Case "0". | ||||||
|  | 		simpl. reflexivity. | ||||||
|  | 	Case "S n'". | ||||||
|  | 		simpl. rewrite -> IHn'. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem remove_decreases_count: forall (s : bag), | ||||||
|  | 	ble_nat (count O (remove_one O s)) (count O s) = true. | ||||||
|  | Proof. | ||||||
|  | 	intros s. | ||||||
|  | 	induction s. | ||||||
|  | 	Case "s = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "s = cons". | ||||||
|  | 		simpl. | ||||||
|  | 		induction n. | ||||||
|  | 		SCase "n = O". | ||||||
|  | 			simpl.  rewrite -> ble_n_Sn. | ||||||
|  | 			reflexivity. | ||||||
|  | 		SCase "n = S n'". | ||||||
|  | 			simpl. | ||||||
|  | 			rewrite -> IHs. | ||||||
|  | 			reflexivity. | ||||||
|  | 			Qed. | ||||||
|  |  | ||||||
|  | Inductive natoption : Type := | ||||||
|  | 	| Some : nat -> natoption | ||||||
|  | 	| None : natoption. | ||||||
|  |  | ||||||
|  | Fixpoint index (n:nat) (l:natlist) : natoption := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => None | ||||||
|  | 		| a :: l' => if beq_nat n O then Some a else index (pred n) l' | ||||||
|  |   end. | ||||||
|  |  | ||||||
|  | Definition option_elim (o : natoption) (d : nat) : nat := | ||||||
|  | 	match o with | ||||||
|  | 		| Some n' => n' | ||||||
|  | 		| None => d | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Definition hd_opt (l : natlist) : natoption := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => None | ||||||
|  | 		| v :: r => Some v | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_hd_opt1 : hd_opt [] = None. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | Example test_hd_opt2 : hd_opt [S O] = Some (S O). | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem option_elim_hd : forall l:natlist, | ||||||
|  | 	head l = option_elim (hd_opt l) O. | ||||||
|  | Proof. | ||||||
|  | 	intros l. | ||||||
|  | 	destruct l. | ||||||
|  | 	reflexivity. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Fixpoint beq_natlist (l1 l2 : natlist) : bool := | ||||||
|  | 	match l1 with | ||||||
|  | 		| nil => match l2 with | ||||||
|  | 							| nil => true | ||||||
|  | 							| _ => false | ||||||
|  | 						 end | ||||||
|  | 		| v1 :: r1 => match l2 with | ||||||
|  | 									 | nil => false | ||||||
|  | 									 | v2 :: r2 => if beq_nat v1 v2 then beq_natlist r1 r2 | ||||||
|  | 																 else false | ||||||
|  | 									end | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_beq_natlist1 : (beq_natlist nil nil = true). | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | Example test_beq_natlist2 : (beq_natlist [S O, S (S O), S (S (S O))] | ||||||
|  | 																				 [S O, S (S O), S (S (S O))] = true). | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem beq_natlist_refl : forall l:natlist, | ||||||
|  | 	beq_natlist l l = true. | ||||||
|  | Proof. | ||||||
|  | 	intros l. | ||||||
|  | 	induction l. | ||||||
|  | 	Case "l = nil". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l = cons". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite <- beq_nat_refl. | ||||||
|  | 		rewrite -> IHl. | ||||||
|  | 		reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem silly1 : forall (n m o p : nat), | ||||||
|  | 	n = m -> [n, o] = [n, p] -> [n, o] = [m, p]. | ||||||
|  | Proof. | ||||||
|  | 	intros n m o p eq1 eq2. | ||||||
|  | 	rewrite <- eq1. | ||||||
|  | 	apply eq2. Qed. | ||||||
|  |  | ||||||
|  | Theorem silly2a : forall (n m : nat), | ||||||
|  | 	(n,n) = (m,m) -> | ||||||
|  | 		(forall (q r : nat), (q, q) = (r, r) -> [q] = [r]) -> | ||||||
|  | 			[n] = [m]. | ||||||
|  | Proof. | ||||||
|  | 	intros n m eq1 eq2. | ||||||
|  | 	apply eq2. | ||||||
|  | 	apply eq1. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem silly_ex : | ||||||
|  | 	(forall n, evenb n = true -> oddb (S n) = true) -> | ||||||
|  | 	evenb (S (S (S O))) = true -> | ||||||
|  | 	oddb (S (S (S (S O)))) = true. | ||||||
|  | Proof. | ||||||
|  | 	intros eq1 eq2. | ||||||
|  | 	apply eq1. | ||||||
|  | 	apply eq2. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem silly3 : forall (n : nat), | ||||||
|  | 	true = beq_nat n (S (S (S (S (S O))))) -> | ||||||
|  | 	beq_nat (S (S n)) (S (S (S (S (S (S (S O))))))) = true. | ||||||
|  | Proof. | ||||||
|  | 	intros n H. | ||||||
|  | 	symmetry. | ||||||
|  | 	apply H. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem rev_exercise : forall (l l' : natlist), | ||||||
|  | 	l = rev l' -> l' = rev l. | ||||||
|  | Proof. | ||||||
|  | 	intros l l' H. | ||||||
|  | 	rewrite -> H. | ||||||
|  | 	rewrite -> rev_involutive. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem beq_nat_sym : forall (n m:nat), forall (b: bool), | ||||||
|  | 	beq_nat n m = b -> beq_nat m n = b. | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	induction n as [| n']. | ||||||
|  | 	Case "n = O". | ||||||
|  | 		intros m b eq1. | ||||||
|  | 		induction m. | ||||||
|  | 		SCase "m = 0". | ||||||
|  | 			apply eq1. | ||||||
|  | 		SCase "m = S m'". | ||||||
|  | 			apply eq1. | ||||||
|  | 	Case "n = S n'". | ||||||
|  | 		induction m. | ||||||
|  | 		SCase "m = 0". | ||||||
|  | 			intros b eq1. | ||||||
|  | 			apply eq1. | ||||||
|  | 		SCase "m = S m'". | ||||||
|  | 			intros b eq1. | ||||||
|  | 			apply IHn'. | ||||||
|  | 			apply eq1. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem app_ass' : forall l1 l2 l3 : natlist, | ||||||
|  | 	(l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3). | ||||||
|  | Proof. | ||||||
|  | 	intros l1. induction l1 as [ | n l1']. | ||||||
|  | 	reflexivity. | ||||||
|  | 	simpl. | ||||||
|  | 	intros l2 l3. | ||||||
|  | 	rewrite -> IHl1'. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | End NatList. | ||||||
							
								
								
									
										547
									
								
								samples/coq/PermutSetoid.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										547
									
								
								samples/coq/PermutSetoid.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,547 @@ | |||||||
|  | (************************************************************************) | ||||||
|  | (*  v      *   The Coq Proof Assistant  /  The Coq Development Team     *) | ||||||
|  | (* <O___,, *   INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010     *) | ||||||
|  | (*   \VV/  **************************************************************) | ||||||
|  | (*    //   *      This file is distributed under the terms of the       *) | ||||||
|  | (*         *       GNU Lesser General Public License Version 2.1        *) | ||||||
|  | (************************************************************************) | ||||||
|  |  | ||||||
|  | Require Import Omega Relations Multiset SetoidList. | ||||||
|  |  | ||||||
|  | (** This file is deprecated, use [Permutation.v] instead. | ||||||
|  |  | ||||||
|  |     Indeed, this file defines a notion of permutation based on | ||||||
|  |     multisets (there exists a permutation between two lists iff every | ||||||
|  |     elements have the same multiplicity in the two lists) which | ||||||
|  |     requires a more complex apparatus (the equipment of the domain | ||||||
|  |     with a decidable equality) than [Permutation] in [Permutation.v]. | ||||||
|  |  | ||||||
|  |     The relation between the two relations are in lemma | ||||||
|  |     [permutation_Permutation]. | ||||||
|  |  | ||||||
|  |     File [Permutation] concerns Leibniz equality : it shows in particular | ||||||
|  |     that [List.Permutation] and [permutation] are equivalent in this context. | ||||||
|  | *) | ||||||
|  |  | ||||||
|  | Set Implicit Arguments. | ||||||
|  |  | ||||||
|  | Local Notation "[ ]" := nil. | ||||||
|  | Local Notation "[ a ; .. ; b ]" := (a :: .. (b :: []) ..). | ||||||
|  |  | ||||||
|  | Section Permut. | ||||||
|  |  | ||||||
|  | (** * From lists to multisets *) | ||||||
|  |  | ||||||
|  | Variable A : Type. | ||||||
|  | Variable eqA : relation A. | ||||||
|  | Hypothesis eqA_equiv : Equivalence eqA. | ||||||
|  | Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}. | ||||||
|  |  | ||||||
|  | Let emptyBag := EmptyBag A. | ||||||
|  | Let singletonBag := SingletonBag _ eqA_dec. | ||||||
|  |  | ||||||
|  | (** contents of a list *) | ||||||
|  |  | ||||||
|  | Fixpoint list_contents (l:list A) : multiset A := | ||||||
|  |   match l with | ||||||
|  |   | [] => emptyBag | ||||||
|  |   | a :: l => munion (singletonBag a) (list_contents l) | ||||||
|  |   end. | ||||||
|  |  | ||||||
|  | Lemma list_contents_app : | ||||||
|  |   forall l m:list A, | ||||||
|  |     meq (list_contents (l ++ m)) (munion (list_contents l) (list_contents m)). | ||||||
|  | Proof. | ||||||
|  |   simple induction l; simpl; auto with datatypes. | ||||||
|  |   intros. | ||||||
|  |   apply meq_trans with | ||||||
|  |     (munion (singletonBag a) (munion (list_contents l0) (list_contents m))); | ||||||
|  |     auto with datatypes. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (** * [permutation]: definition and basic properties *) | ||||||
|  |  | ||||||
|  | Definition permutation (l m:list A) := meq (list_contents l) (list_contents m). | ||||||
|  |  | ||||||
|  | Lemma permut_refl : forall l:list A, permutation l l. | ||||||
|  | Proof. | ||||||
|  |   unfold permutation; auto with datatypes. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_sym : | ||||||
|  |   forall l1 l2 : list A, permutation l1 l2 -> permutation l2 l1. | ||||||
|  | Proof. | ||||||
|  |   unfold permutation, meq; intros; symmetry; trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_trans : | ||||||
|  |   forall l m n:list A, permutation l m -> permutation m n -> permutation l n. | ||||||
|  | Proof. | ||||||
|  |   unfold permutation; intros. | ||||||
|  |   apply meq_trans with (list_contents m); auto with datatypes. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_cons_eq : | ||||||
|  |   forall l m:list A, | ||||||
|  |     permutation l m -> forall a a', eqA a a' -> permutation (a :: l) (a' :: m). | ||||||
|  | Proof. | ||||||
|  |   unfold permutation; simpl; intros. | ||||||
|  |   apply meq_trans with (munion (singletonBag a') (list_contents l)). | ||||||
|  |   apply meq_left, meq_singleton; auto. | ||||||
|  |   auto with datatypes. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_cons : | ||||||
|  |   forall l m:list A, | ||||||
|  |     permutation l m -> forall a:A, permutation (a :: l) (a :: m). | ||||||
|  | Proof. | ||||||
|  |   unfold permutation; simpl; auto with datatypes. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_app : | ||||||
|  |   forall l l' m m':list A, | ||||||
|  |     permutation l l' -> permutation m m' -> permutation (l ++ m) (l' ++ m'). | ||||||
|  | Proof. | ||||||
|  |   unfold permutation; intros. | ||||||
|  |   apply meq_trans with (munion (list_contents l) (list_contents m)); | ||||||
|  |     auto using permut_cons, list_contents_app with datatypes. | ||||||
|  |   apply meq_trans with (munion (list_contents l') (list_contents m')); | ||||||
|  |     auto using permut_cons, list_contents_app with datatypes. | ||||||
|  |   apply meq_trans with (munion (list_contents l') (list_contents m)); | ||||||
|  |     auto using permut_cons, list_contents_app with datatypes. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_add_inside_eq : | ||||||
|  |   forall a a' l1 l2 l3 l4, eqA a a' -> | ||||||
|  |     permutation (l1 ++ l2) (l3 ++ l4) -> | ||||||
|  |     permutation (l1 ++ a :: l2) (l3 ++ a' :: l4). | ||||||
|  | Proof. | ||||||
|  |   unfold permutation, meq in *; intros. | ||||||
|  |   specialize H0 with a0. | ||||||
|  |   repeat rewrite list_contents_app in *; simpl in *. | ||||||
|  |   destruct (eqA_dec a a0) as [Ha|Ha]; rewrite H in Ha; | ||||||
|  |     decide (eqA_dec a' a0) with Ha; simpl; auto with arith. | ||||||
|  |   do 2 rewrite <- plus_n_Sm; f_equal; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_add_inside : | ||||||
|  |   forall a l1 l2 l3 l4, | ||||||
|  |     permutation (l1 ++ l2) (l3 ++ l4) -> | ||||||
|  |     permutation (l1 ++ a :: l2) (l3 ++ a :: l4). | ||||||
|  | Proof. | ||||||
|  |   unfold permutation, meq in *; intros. | ||||||
|  |   generalize (H a0); clear H. | ||||||
|  |   do 4 rewrite list_contents_app. | ||||||
|  |   simpl. | ||||||
|  |   destruct (eqA_dec a a0); simpl; auto with arith. | ||||||
|  |   do 2 rewrite <- plus_n_Sm; f_equal; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_add_cons_inside_eq : | ||||||
|  |   forall a a' l l1 l2, eqA a a' -> | ||||||
|  |     permutation l (l1 ++ l2) -> | ||||||
|  |     permutation (a :: l) (l1 ++ a' :: l2). | ||||||
|  | Proof. | ||||||
|  |   intros; | ||||||
|  |   replace (a :: l) with ([] ++ a :: l); trivial; | ||||||
|  |     apply permut_add_inside_eq; trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_add_cons_inside : | ||||||
|  |   forall a l l1 l2, | ||||||
|  |     permutation l (l1 ++ l2) -> | ||||||
|  |     permutation (a :: l) (l1 ++ a :: l2). | ||||||
|  | Proof. | ||||||
|  |   intros; | ||||||
|  |     replace (a :: l) with ([] ++ a :: l); trivial; | ||||||
|  | 	apply permut_add_inside; trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_middle : | ||||||
|  |   forall (l m:list A) (a:A), permutation (a :: l ++ m) (l ++ a :: m). | ||||||
|  | Proof. | ||||||
|  |   intros; apply permut_add_cons_inside; auto using permut_sym, permut_refl. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_sym_app : | ||||||
|  |   forall l1 l2, permutation (l1 ++ l2) (l2 ++ l1). | ||||||
|  | Proof. | ||||||
|  |   intros l1 l2; | ||||||
|  |     unfold permutation, meq; | ||||||
|  | 	intro a; do 2 rewrite list_contents_app; simpl; | ||||||
|  | 	  auto with arith. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_rev : | ||||||
|  |   forall l, permutation l (rev l). | ||||||
|  | Proof. | ||||||
|  |   induction l. | ||||||
|  |   simpl; trivial using permut_refl. | ||||||
|  |   simpl. | ||||||
|  |   apply permut_add_cons_inside. | ||||||
|  |   rewrite <- app_nil_end. trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (** * Some inversion results. *) | ||||||
|  | Lemma permut_conv_inv : | ||||||
|  |   forall e l1 l2, permutation (e :: l1) (e :: l2) -> permutation l1 l2. | ||||||
|  | Proof. | ||||||
|  |   intros e l1 l2; unfold permutation, meq; simpl; intros H a; | ||||||
|  |     generalize (H a); apply plus_reg_l. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_app_inv1 : | ||||||
|  |   forall l l1 l2, permutation (l1 ++ l) (l2 ++ l) -> permutation l1 l2. | ||||||
|  | Proof. | ||||||
|  |   intros l l1 l2; unfold permutation, meq; simpl; | ||||||
|  |     intros H a; generalize (H a); clear H. | ||||||
|  |   do 2 rewrite list_contents_app. | ||||||
|  |   simpl. | ||||||
|  |   intros; apply plus_reg_l with (multiplicity (list_contents l) a). | ||||||
|  |   rewrite plus_comm; rewrite H; rewrite plus_comm. | ||||||
|  |   trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (** we can use [multiplicity] to define [InA] and [NoDupA]. *) | ||||||
|  |  | ||||||
|  | Fact if_eqA_then : forall a a' (B:Type)(b b':B), | ||||||
|  |  eqA a a' -> (if eqA_dec a a' then b else b') = b. | ||||||
|  | Proof. | ||||||
|  |   intros. destruct eqA_dec as [_|NEQ]; auto. | ||||||
|  |   contradict NEQ; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_app_inv2 : | ||||||
|  |   forall l l1 l2, permutation (l ++ l1) (l ++ l2) -> permutation l1 l2. | ||||||
|  | Proof. | ||||||
|  |   intros l l1 l2; unfold permutation, meq; simpl; | ||||||
|  |     intros H a; generalize (H a); clear H. | ||||||
|  |   do 2 rewrite list_contents_app. | ||||||
|  |   simpl. | ||||||
|  |   intros; apply plus_reg_l with (multiplicity (list_contents l) a). | ||||||
|  |   trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_remove_hd_eq : | ||||||
|  |   forall l l1 l2 a b, eqA a b -> | ||||||
|  |     permutation (a :: l) (l1 ++ b :: l2) -> permutation l (l1 ++ l2). | ||||||
|  | Proof. | ||||||
|  |   unfold permutation, meq; simpl; intros l l1 l2 a b Heq H a0. | ||||||
|  |   specialize H with a0. | ||||||
|  |   rewrite list_contents_app in *; simpl in *. | ||||||
|  |   apply plus_reg_l with (if eqA_dec a a0 then 1 else 0). | ||||||
|  |   rewrite H; clear H. | ||||||
|  |   symmetry; rewrite plus_comm, <- ! plus_assoc; f_equal. | ||||||
|  |   rewrite plus_comm. | ||||||
|  |   destruct (eqA_dec a a0) as [Ha|Ha]; rewrite Heq in Ha; | ||||||
|  |     decide (eqA_dec b a0) with Ha; reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_remove_hd : | ||||||
|  |   forall l l1 l2 a, | ||||||
|  |     permutation (a :: l) (l1 ++ a :: l2) -> permutation l (l1 ++ l2). | ||||||
|  | Proof. | ||||||
|  |   eauto using permut_remove_hd_eq, Equivalence_Reflexive. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Fact if_eqA_else : forall a a' (B:Type)(b b':B), | ||||||
|  |  ~eqA a a' -> (if eqA_dec a a' then b else b') = b'. | ||||||
|  | Proof. | ||||||
|  |   intros. decide (eqA_dec a a') with H; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Fact if_eqA_refl : forall a (B:Type)(b b':B), | ||||||
|  |  (if eqA_dec a a then b else b') = b. | ||||||
|  | Proof. | ||||||
|  |   intros; apply (decide_left (eqA_dec a a)); auto with *. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (** PL: Inutilisable dans un rewrite sans un change prealable. *) | ||||||
|  |  | ||||||
|  | Global Instance if_eqA (B:Type)(b b':B) : | ||||||
|  |  Proper (eqA==>eqA==>@eq _) (fun x y => if eqA_dec x y then b else b'). | ||||||
|  | Proof. | ||||||
|  |  intros x x' Hxx' y y' Hyy'. | ||||||
|  |  intros; destruct (eqA_dec x y) as [H|H]; | ||||||
|  |   destruct (eqA_dec x' y') as [H'|H']; auto. | ||||||
|  |  contradict H'; transitivity x; auto with *; transitivity y; auto with *. | ||||||
|  |  contradict H; transitivity x'; auto with *; transitivity y'; auto with *. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Fact if_eqA_rewrite_l : forall a1 a1' a2 (B:Type)(b b':B), | ||||||
|  |  eqA a1 a1' -> (if eqA_dec a1 a2 then b else b') = | ||||||
|  |                (if eqA_dec a1' a2 then b else b'). | ||||||
|  | Proof. | ||||||
|  |  intros; destruct (eqA_dec a1 a2) as [A1|A1]; | ||||||
|  |   destruct (eqA_dec a1' a2) as [A1'|A1']; auto. | ||||||
|  |  contradict A1'; transitivity a1; eauto with *. | ||||||
|  |  contradict A1; transitivity a1'; eauto with *. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Fact if_eqA_rewrite_r : forall a1 a2 a2' (B:Type)(b b':B), | ||||||
|  |  eqA a2 a2' -> (if eqA_dec a1 a2 then b else b') = | ||||||
|  |                (if eqA_dec a1 a2' then b else b'). | ||||||
|  | Proof. | ||||||
|  |  intros; destruct (eqA_dec a1 a2) as [A2|A2]; | ||||||
|  |   destruct (eqA_dec a1 a2') as [A2'|A2']; auto. | ||||||
|  |  contradict A2'; transitivity a2; eauto with *. | ||||||
|  |  contradict A2; transitivity a2'; eauto with *. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Global Instance multiplicity_eqA (l:list A) : | ||||||
|  |  Proper (eqA==>@eq _) (multiplicity (list_contents l)). | ||||||
|  | Proof. | ||||||
|  |   intros x x' Hxx'. | ||||||
|  |   induction l as [|y l Hl]; simpl; auto. | ||||||
|  |   rewrite (@if_eqA_rewrite_r y x x'); auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma multiplicity_InA : | ||||||
|  |   forall l a, InA eqA a l <-> 0 < multiplicity (list_contents l) a. | ||||||
|  | Proof. | ||||||
|  |   induction l. | ||||||
|  |   simpl. | ||||||
|  |   split; inversion 1. | ||||||
|  |   simpl. | ||||||
|  |   intros a'; split; intros H. inversion_clear H. | ||||||
|  |   apply (decide_left (eqA_dec a a')); auto with *. | ||||||
|  |   destruct (eqA_dec a a'); auto with *. simpl; rewrite <- IHl; auto. | ||||||
|  |   destruct (eqA_dec a a'); auto with *. right. rewrite IHl; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma multiplicity_InA_O : | ||||||
|  |   forall l a, ~ InA eqA a l -> multiplicity (list_contents l) a = 0. | ||||||
|  | Proof. | ||||||
|  |   intros l a; rewrite multiplicity_InA; | ||||||
|  |     destruct (multiplicity (list_contents l) a); auto with arith. | ||||||
|  |   destruct 1; auto with arith. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma multiplicity_InA_S : | ||||||
|  |   forall l a, InA eqA a l -> multiplicity (list_contents l) a >= 1. | ||||||
|  | Proof. | ||||||
|  |   intros l a; rewrite multiplicity_InA; auto with arith. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma multiplicity_NoDupA : forall l, | ||||||
|  |   NoDupA eqA l <-> (forall a, multiplicity (list_contents l) a <= 1). | ||||||
|  | Proof. | ||||||
|  |   induction l. | ||||||
|  |   simpl. | ||||||
|  |   split; auto with arith. | ||||||
|  |   split; simpl. | ||||||
|  |   inversion_clear 1. | ||||||
|  |   rewrite IHl in H1. | ||||||
|  |   intros; destruct (eqA_dec a a0) as [EQ|NEQ]; simpl; auto with *. | ||||||
|  |   rewrite <- EQ. | ||||||
|  |   rewrite multiplicity_InA_O; auto. | ||||||
|  |   intros; constructor. | ||||||
|  |   rewrite multiplicity_InA. | ||||||
|  |   specialize (H a). | ||||||
|  |   rewrite if_eqA_refl in H. | ||||||
|  |   clear IHl; omega. | ||||||
|  |   rewrite IHl; intros. | ||||||
|  |   specialize (H a0). omega. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (** Permutation is compatible with InA. *) | ||||||
|  | Lemma permut_InA_InA : | ||||||
|  |   forall l1 l2 e, permutation l1 l2 -> InA eqA e l1 -> InA eqA e l2. | ||||||
|  | Proof. | ||||||
|  |   intros l1 l2 e. | ||||||
|  |   do 2 rewrite multiplicity_InA. | ||||||
|  |   unfold permutation, meq. | ||||||
|  |   intros H;rewrite H; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_cons_InA : | ||||||
|  |   forall l1 l2 e, permutation (e :: l1) l2 -> InA eqA e l2. | ||||||
|  | Proof. | ||||||
|  |   intros; apply (permut_InA_InA (e:=e) H); auto with *. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (** Permutation of an empty list. *) | ||||||
|  | Lemma permut_nil : | ||||||
|  |   forall l, permutation l [] -> l = []. | ||||||
|  | Proof. | ||||||
|  |   intro l; destruct l as [ | e l ]; trivial. | ||||||
|  |   assert (InA eqA e (e::l)) by (auto with *). | ||||||
|  |   intro Abs; generalize (permut_InA_InA Abs H). | ||||||
|  |   inversion 1. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (** Permutation for short lists. *) | ||||||
|  |  | ||||||
|  | Lemma permut_length_1: | ||||||
|  |   forall a b, permutation [a] [b] -> eqA a b. | ||||||
|  | Proof. | ||||||
|  |   intros a b; unfold permutation, meq. | ||||||
|  |   intro P; specialize (P b); simpl in *. | ||||||
|  |   rewrite if_eqA_refl in *. | ||||||
|  |   destruct (eqA_dec a b); simpl; auto; discriminate. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_length_2 : | ||||||
|  |   forall a1 b1 a2 b2, permutation [a1; b1] [a2; b2] -> | ||||||
|  |     (eqA a1 a2) /\ (eqA b1 b2) \/ (eqA a1 b2) /\ (eqA a2 b1). | ||||||
|  | Proof. | ||||||
|  |   intros a1 b1 a2 b2 P. | ||||||
|  |   assert (H:=permut_cons_InA P). | ||||||
|  |   inversion_clear H. | ||||||
|  |   left; split; auto. | ||||||
|  |   apply permut_length_1. | ||||||
|  |   red; red; intros. | ||||||
|  |   specialize (P a). simpl in *. | ||||||
|  |   rewrite (@if_eqA_rewrite_l a1 a2 a) in P by auto. omega. | ||||||
|  |   right. | ||||||
|  |   inversion_clear H0; [|inversion H]. | ||||||
|  |   split; auto. | ||||||
|  |   apply permut_length_1. | ||||||
|  |   red; red; intros. | ||||||
|  |   specialize (P a); simpl in *. | ||||||
|  |   rewrite (@if_eqA_rewrite_l a1 b2 a) in P by auto. omega. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (** Permutation is compatible with length. *) | ||||||
|  | Lemma permut_length : | ||||||
|  |   forall l1 l2, permutation l1 l2 -> length l1 = length l2. | ||||||
|  | Proof. | ||||||
|  |   induction l1; intros l2 H. | ||||||
|  |   rewrite (permut_nil (permut_sym H)); auto. | ||||||
|  |   assert (H0:=permut_cons_InA H). | ||||||
|  |   destruct (InA_split H0) as (h2,(b,(t2,(H1,H2)))). | ||||||
|  |   subst l2. | ||||||
|  |   rewrite app_length. | ||||||
|  |   simpl; rewrite <- plus_n_Sm; f_equal. | ||||||
|  |   rewrite <- app_length. | ||||||
|  |   apply IHl1. | ||||||
|  |   apply permut_remove_hd with b. | ||||||
|  |   apply permut_trans with (a::l1); auto. | ||||||
|  |   revert H1; unfold permutation, meq; simpl. | ||||||
|  |   intros; f_equal; auto. | ||||||
|  |   rewrite (@if_eqA_rewrite_l a b a0); auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma NoDupA_equivlistA_permut : | ||||||
|  |   forall l l', NoDupA eqA l -> NoDupA eqA l' -> | ||||||
|  |     equivlistA eqA l l' -> permutation l l'. | ||||||
|  | Proof. | ||||||
|  |   intros. | ||||||
|  |   red; unfold meq; intros. | ||||||
|  |   rewrite multiplicity_NoDupA in H, H0. | ||||||
|  |   generalize (H a) (H0 a) (H1 a); clear H H0 H1. | ||||||
|  |   do 2 rewrite multiplicity_InA. | ||||||
|  |   destruct 3; omega. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Permut. | ||||||
|  |  | ||||||
|  | Section Permut_map. | ||||||
|  |  | ||||||
|  | Variables A B : Type. | ||||||
|  |  | ||||||
|  | Variable eqA : relation A. | ||||||
|  | Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}. | ||||||
|  | Hypothesis eqA_equiv : Equivalence eqA. | ||||||
|  |  | ||||||
|  | Variable eqB : B->B->Prop. | ||||||
|  | Hypothesis eqB_dec : forall x y:B, { eqB x y }+{ ~eqB x y }. | ||||||
|  | Hypothesis eqB_trans : Transitive eqB. | ||||||
|  |  | ||||||
|  | (** Permutation is compatible with map. *) | ||||||
|  |  | ||||||
|  | Lemma permut_map : | ||||||
|  |   forall f, | ||||||
|  |     (Proper (eqA==>eqB) f) -> | ||||||
|  |     forall l1 l2, permutation _ eqA_dec l1 l2 -> | ||||||
|  |       permutation _ eqB_dec (map f l1) (map f l2). | ||||||
|  | Proof. | ||||||
|  |   intros f; induction l1. | ||||||
|  |   intros l2 P; rewrite (permut_nil eqA_equiv (permut_sym P)); apply permut_refl. | ||||||
|  |   intros l2 P. | ||||||
|  |   simpl. | ||||||
|  |   assert (H0:=permut_cons_InA eqA_equiv P). | ||||||
|  |   destruct (InA_split H0) as (h2,(b,(t2,(H1,H2)))). | ||||||
|  |   subst l2. | ||||||
|  |   rewrite map_app. | ||||||
|  |   simpl. | ||||||
|  |   apply permut_trans with (f b :: map f l1). | ||||||
|  |   revert H1; unfold permutation, meq; simpl. | ||||||
|  |   intros; f_equal; auto. | ||||||
|  |   destruct (eqB_dec (f b) a0) as [H2|H2]; | ||||||
|  |     destruct (eqB_dec (f a) a0) as [H3|H3]; auto. | ||||||
|  |   destruct H3; transitivity (f b); auto with *. | ||||||
|  |   destruct H2; transitivity (f a); auto with *. | ||||||
|  |   apply permut_add_cons_inside. | ||||||
|  |   rewrite <- map_app. | ||||||
|  |   apply IHl1; auto. | ||||||
|  |   apply permut_remove_hd with b; trivial. | ||||||
|  |   apply permut_trans with (a::l1); auto. | ||||||
|  |   revert H1; unfold permutation, meq; simpl. | ||||||
|  |   intros; f_equal; auto. | ||||||
|  |   rewrite (@if_eqA_rewrite_l _ _ eqA_equiv eqA_dec a b a0); auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Permut_map. | ||||||
|  |  | ||||||
|  | Require Import Permutation. | ||||||
|  |  | ||||||
|  | Section Permut_permut. | ||||||
|  |  | ||||||
|  | Variable A : Type. | ||||||
|  |  | ||||||
|  | Variable eqA : relation A. | ||||||
|  | Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}. | ||||||
|  | Hypothesis eqA_equiv : Equivalence eqA. | ||||||
|  |  | ||||||
|  | Lemma Permutation_impl_permutation : forall l l', | ||||||
|  |   Permutation l l' -> permutation _ eqA_dec l l'. | ||||||
|  | Proof. | ||||||
|  |   induction 1. | ||||||
|  |     apply permut_refl. | ||||||
|  |     apply permut_cons; auto using Equivalence_Reflexive. | ||||||
|  |     change (x :: y :: l) with ([x] ++ y :: l); | ||||||
|  |       apply permut_add_cons_inside; simpl; | ||||||
|  |       apply permut_cons_eq; auto using Equivalence_Reflexive, permut_refl. | ||||||
|  |     apply permut_trans with l'; trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permut_eqA : forall l l', Forall2 eqA l l' -> permutation _ eqA_dec l l'. | ||||||
|  | Proof. | ||||||
|  |   induction 1. | ||||||
|  |     apply permut_refl. | ||||||
|  |     apply permut_cons_eq; trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma permutation_Permutation : forall l l', | ||||||
|  |   permutation _ eqA_dec l l' <-> | ||||||
|  |   exists l'', Permutation l l'' /\ Forall2 eqA l'' l'. | ||||||
|  | Proof. | ||||||
|  |   split; intro H. | ||||||
|  |   (* -> *) | ||||||
|  |   induction l in l', H |- *. | ||||||
|  |     exists []; apply permut_sym, permut_nil in H as ->; auto using Forall2. | ||||||
|  |     pose proof H as H'. | ||||||
|  |     apply permut_cons_InA, InA_split in H | ||||||
|  |       as (l1 & y & l2 & Heq & ->); trivial. | ||||||
|  |     apply permut_remove_hd_eq, IHl in H' | ||||||
|  |       as (l'' & IHP & IHA); clear IHl; trivial. | ||||||
|  |     apply Forall2_app_inv_r in IHA as (l1'' & l2'' & Hl1 & Hl2 & ->). | ||||||
|  |     exists (l1'' ++ a :: l2''); split. | ||||||
|  |       apply Permutation_cons_app; trivial. | ||||||
|  |       apply Forall2_app, Forall2_cons; trivial. | ||||||
|  |   (* <- *) | ||||||
|  |   destruct H as (l'' & H & Heq). | ||||||
|  |   apply permut_trans with l''. | ||||||
|  |     apply Permutation_impl_permutation; trivial. | ||||||
|  |     apply permut_eqA; trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Permut_permut. | ||||||
|  |  | ||||||
|  | (* begin hide *) | ||||||
|  | (** For compatibilty *) | ||||||
|  | Notation permut_right := permut_cons (only parsing). | ||||||
|  | Notation permut_tran := permut_trans (only parsing). | ||||||
|  | (* end hide *) | ||||||
							
								
								
									
										644
									
								
								samples/coq/Permutation.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										644
									
								
								samples/coq/Permutation.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,644 @@ | |||||||
|  | (************************************************************************) | ||||||
|  | (*  v      *   The Coq Proof Assistant  /  The Coq Development Team     *) | ||||||
|  | (* <O___,, *   INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010     *) | ||||||
|  | (*   \VV/  **************************************************************) | ||||||
|  | (*    //   *      This file is distributed under the terms of the       *) | ||||||
|  | (*         *       GNU Lesser General Public License Version 2.1        *) | ||||||
|  | (************************************************************************) | ||||||
|  |  | ||||||
|  | (*********************************************************************) | ||||||
|  | (** * List permutations as a composition of adjacent transpositions  *) | ||||||
|  | (*********************************************************************) | ||||||
|  |  | ||||||
|  | (* Adapted in May 2006 by Jean-Marc Notin from initial contents by | ||||||
|  |    Laurent Théry (Huffmann contribution, October 2003) *) | ||||||
|  |  | ||||||
|  | Require Import List Setoid Compare_dec Morphisms. | ||||||
|  | Import ListNotations. (* For notations [] and [a;b;c] *) | ||||||
|  | Set Implicit Arguments. | ||||||
|  |  | ||||||
|  | Section Permutation. | ||||||
|  |  | ||||||
|  | Variable A:Type. | ||||||
|  |  | ||||||
|  | Inductive Permutation : list A -> list A -> Prop := | ||||||
|  | | perm_nil: Permutation [] [] | ||||||
|  | | perm_skip x l l' : Permutation l l' -> Permutation (x::l) (x::l') | ||||||
|  | | perm_swap x y l : Permutation (y::x::l) (x::y::l) | ||||||
|  | | perm_trans l l' l'' : | ||||||
|  |     Permutation l l' -> Permutation l' l'' -> Permutation l l''. | ||||||
|  |  | ||||||
|  | Local Hint Constructors Permutation. | ||||||
|  |  | ||||||
|  | (** Some facts about [Permutation] *) | ||||||
|  |  | ||||||
|  | Theorem Permutation_nil : forall (l : list A), Permutation [] l -> l = []. | ||||||
|  | Proof. | ||||||
|  |   intros l HF. | ||||||
|  |   remember (@nil A) as m in HF. | ||||||
|  |   induction HF; discriminate || auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_nil_cons : forall (l : list A) (x : A), | ||||||
|  |  ~ Permutation nil (x::l). | ||||||
|  | Proof. | ||||||
|  |   intros l x HF. | ||||||
|  |   apply Permutation_nil in HF; discriminate. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (** Permutation over lists is a equivalence relation *) | ||||||
|  |  | ||||||
|  | Theorem Permutation_refl : forall l : list A, Permutation l l. | ||||||
|  | Proof. | ||||||
|  |   induction l; constructor. exact IHl. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_sym : forall l l' : list A, | ||||||
|  |  Permutation l l' -> Permutation l' l. | ||||||
|  | Proof. | ||||||
|  |   intros l l' Hperm; induction Hperm; auto. | ||||||
|  |   apply perm_trans with (l':=l'); assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_trans : forall l l' l'' : list A, | ||||||
|  |  Permutation l l' -> Permutation l' l'' -> Permutation l l''. | ||||||
|  | Proof. | ||||||
|  |   exact perm_trans. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Permutation. | ||||||
|  |  | ||||||
|  | Hint Resolve Permutation_refl perm_nil perm_skip. | ||||||
|  |  | ||||||
|  | (* These hints do not reduce the size of the problem to solve and they | ||||||
|  |    must be used with care to avoid combinatoric explosions *) | ||||||
|  |  | ||||||
|  | Local Hint Resolve perm_swap perm_trans. | ||||||
|  | Local Hint Resolve Permutation_sym Permutation_trans. | ||||||
|  |  | ||||||
|  | (* This provides reflexivity, symmetry and transitivity and rewriting | ||||||
|  |    on morphims to come *) | ||||||
|  |  | ||||||
|  | Instance Permutation_Equivalence A : Equivalence (@Permutation A) | 10 := { | ||||||
|  |   Equivalence_Reflexive := @Permutation_refl A ; | ||||||
|  |   Equivalence_Symmetric := @Permutation_sym A ; | ||||||
|  |   Equivalence_Transitive := @Permutation_trans A }. | ||||||
|  |  | ||||||
|  | Instance Permutation_cons A : | ||||||
|  |  Proper (Logic.eq ==> @Permutation A ==> @Permutation A) (@cons A) | 10. | ||||||
|  | Proof. | ||||||
|  |   repeat intro; subst; auto using perm_skip. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Section Permutation_properties. | ||||||
|  |  | ||||||
|  | Variable A:Type. | ||||||
|  |  | ||||||
|  | Implicit Types a b : A. | ||||||
|  | Implicit Types l m : list A. | ||||||
|  |  | ||||||
|  | (** Compatibility with others operations on lists *) | ||||||
|  |  | ||||||
|  | Theorem Permutation_in : forall (l l' : list A) (x : A), | ||||||
|  |  Permutation l l' -> In x l -> In x l'. | ||||||
|  | Proof. | ||||||
|  |   intros l l' x Hperm; induction Hperm; simpl; tauto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Global Instance Permutation_in' : | ||||||
|  |  Proper (Logic.eq ==> @Permutation A ==> iff) (@In A) | 10. | ||||||
|  | Proof. | ||||||
|  |   repeat red; intros; subst; eauto using Permutation_in. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_app_tail : forall (l l' tl : list A), | ||||||
|  |  Permutation l l' -> Permutation (l++tl) (l'++tl). | ||||||
|  | Proof. | ||||||
|  |   intros l l' tl Hperm; induction Hperm as [|x l l'|x y l|l l' l'']; simpl; auto. | ||||||
|  |   eapply Permutation_trans with (l':=l'++tl); trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_app_head : forall (l tl tl' : list A), | ||||||
|  |  Permutation tl tl' -> Permutation (l++tl) (l++tl'). | ||||||
|  | Proof. | ||||||
|  |   intros l tl tl' Hperm; induction l; | ||||||
|  |    [trivial | repeat rewrite <- app_comm_cons; constructor; assumption]. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_app : forall (l m l' m' : list A), | ||||||
|  |  Permutation l l' -> Permutation m m' -> Permutation (l++m) (l'++m'). | ||||||
|  | Proof. | ||||||
|  |   intros l m l' m' Hpermll' Hpermmm'; | ||||||
|  |    induction Hpermll' as [|x l l'|x y l|l l' l'']; | ||||||
|  |     repeat rewrite <- app_comm_cons; auto. | ||||||
|  |   apply Permutation_trans with (l' := (x :: y :: l ++ m)); | ||||||
|  |    [idtac | repeat rewrite app_comm_cons; apply Permutation_app_head]; trivial. | ||||||
|  |   apply Permutation_trans with (l' := (l' ++ m')); try assumption. | ||||||
|  |   apply Permutation_app_tail; assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Global Instance Permutation_app' : | ||||||
|  |  Proper (@Permutation A ==> @Permutation A ==> @Permutation A) (@app A) | 10. | ||||||
|  | Proof. | ||||||
|  |   repeat intro; now apply Permutation_app. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_add_inside : forall a (l l' tl tl' : list A), | ||||||
|  |   Permutation l l' -> Permutation tl tl' -> | ||||||
|  |   Permutation (l ++ a :: tl) (l' ++ a :: tl'). | ||||||
|  | Proof. | ||||||
|  |   intros; apply Permutation_app; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_cons_append : forall (l : list A) x, | ||||||
|  |   Permutation (x :: l) (l ++ x :: nil). | ||||||
|  | Proof. induction l; intros; auto. simpl. rewrite <- IHl; auto. Qed. | ||||||
|  | Local Hint Resolve Permutation_cons_append. | ||||||
|  |  | ||||||
|  | Theorem Permutation_app_comm : forall (l l' : list A), | ||||||
|  |   Permutation (l ++ l') (l' ++ l). | ||||||
|  | Proof. | ||||||
|  |   induction l as [|x l]; simpl; intro l'. | ||||||
|  |   rewrite app_nil_r; trivial. rewrite IHl. | ||||||
|  |   rewrite app_comm_cons, Permutation_cons_append. | ||||||
|  |   now rewrite <- app_assoc. | ||||||
|  | Qed. | ||||||
|  | Local Hint Resolve Permutation_app_comm. | ||||||
|  |  | ||||||
|  | Theorem Permutation_cons_app : forall (l l1 l2:list A) a, | ||||||
|  |   Permutation l (l1 ++ l2) -> Permutation (a :: l) (l1 ++ a :: l2). | ||||||
|  | Proof. | ||||||
|  |   intros l l1 l2 a H. rewrite H. | ||||||
|  |   rewrite app_comm_cons, Permutation_cons_append. | ||||||
|  |   now rewrite <- app_assoc. | ||||||
|  | Qed. | ||||||
|  | Local Hint Resolve Permutation_cons_app. | ||||||
|  |  | ||||||
|  | Theorem Permutation_middle : forall (l1 l2:list A) a, | ||||||
|  |   Permutation (a :: l1 ++ l2) (l1 ++ a :: l2). | ||||||
|  | Proof. | ||||||
|  |   auto. | ||||||
|  | Qed. | ||||||
|  | Local Hint Resolve Permutation_middle. | ||||||
|  |  | ||||||
|  | Theorem Permutation_rev : forall (l : list A), Permutation l (rev l). | ||||||
|  | Proof. | ||||||
|  |   induction l as [| x l]; simpl; trivial. now rewrite IHl at 1. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Global Instance Permutation_rev' : | ||||||
|  |  Proper (@Permutation A ==> @Permutation A) (@rev A) | 10. | ||||||
|  | Proof. | ||||||
|  |   repeat intro; now rewrite <- 2 Permutation_rev. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_length : forall (l l' : list A), | ||||||
|  |  Permutation l l' -> length l = length l'. | ||||||
|  | Proof. | ||||||
|  |   intros l l' Hperm; induction Hperm; simpl; auto. now transitivity (length l'). | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Global Instance Permutation_length' : | ||||||
|  |  Proper (@Permutation A ==> Logic.eq) (@length A) | 10. | ||||||
|  | Proof. | ||||||
|  |   exact Permutation_length. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_ind_bis : | ||||||
|  |  forall P : list A -> list A -> Prop, | ||||||
|  |    P [] [] -> | ||||||
|  |    (forall x l l', Permutation l l' -> P l l' -> P (x :: l) (x :: l')) -> | ||||||
|  |    (forall x y l l', Permutation l l' -> P l l' -> P (y :: x :: l) (x :: y :: l')) -> | ||||||
|  |    (forall l l' l'', Permutation l l' -> P l l' -> Permutation l' l'' -> P l' l'' -> P l l'') -> | ||||||
|  |    forall l l', Permutation l l' -> P l l'. | ||||||
|  | Proof. | ||||||
|  |   intros P Hnil Hskip Hswap Htrans. | ||||||
|  |   induction 1; auto. | ||||||
|  |   apply Htrans with (x::y::l); auto. | ||||||
|  |   apply Hswap; auto. | ||||||
|  |   induction l; auto. | ||||||
|  |   apply Hskip; auto. | ||||||
|  |   apply Hskip; auto. | ||||||
|  |   induction l; auto. | ||||||
|  |   eauto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Ltac break_list l x l' H := | ||||||
|  |   destruct l as [|x l']; simpl in *; | ||||||
|  |   injection H; intros; subst; clear H. | ||||||
|  |  | ||||||
|  | Theorem Permutation_nil_app_cons : forall (l l' : list A) (x : A), | ||||||
|  |  ~ Permutation nil (l++x::l'). | ||||||
|  | Proof. | ||||||
|  |   intros l l' x HF. | ||||||
|  |   apply Permutation_nil in HF. destruct l; discriminate. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_app_inv : forall (l1 l2 l3 l4:list A) a, | ||||||
|  |   Permutation (l1++a::l2) (l3++a::l4) -> Permutation (l1++l2) (l3 ++ l4). | ||||||
|  | Proof. | ||||||
|  |   intros l1 l2 l3 l4 a; revert l1 l2 l3 l4. | ||||||
|  |   set (P l l' := | ||||||
|  |        forall l1 l2 l3 l4, l=l1++a::l2 -> l'=l3++a::l4 -> | ||||||
|  |        Permutation (l1++l2) (l3++l4)). | ||||||
|  |   cut (forall l l', Permutation l l' -> P l l'). | ||||||
|  |   intros H; intros; eapply H; eauto. | ||||||
|  |   apply (Permutation_ind_bis P); unfold P; clear P. | ||||||
|  |   - (* nil *) | ||||||
|  |     intros; now destruct l1. | ||||||
|  |   - (* skip *) | ||||||
|  |     intros x l l' H IH; intros. | ||||||
|  |     break_list l1 b l1' H0; break_list l3 c l3' H1. | ||||||
|  |     auto. | ||||||
|  |     now rewrite H. | ||||||
|  |     now rewrite <- H. | ||||||
|  |     now rewrite (IH _ _ _ _ eq_refl eq_refl). | ||||||
|  |   - (* swap *) | ||||||
|  |     intros x y l l' Hp IH; intros. | ||||||
|  |     break_list l1 b l1' H; break_list l3 c l3' H0. | ||||||
|  |     auto. | ||||||
|  |     break_list l3' b l3'' H. | ||||||
|  |     auto. | ||||||
|  |     constructor. now rewrite Permutation_middle. | ||||||
|  |     break_list l1' c l1'' H1. | ||||||
|  |     auto. | ||||||
|  |     constructor. now rewrite Permutation_middle. | ||||||
|  |     break_list l3' d l3'' H; break_list l1' e l1'' H1. | ||||||
|  |     auto. | ||||||
|  |     rewrite perm_swap. constructor. now rewrite Permutation_middle. | ||||||
|  |     rewrite perm_swap. constructor. now rewrite Permutation_middle. | ||||||
|  |     now rewrite perm_swap, (IH _ _ _ _ eq_refl eq_refl). | ||||||
|  |   - (*trans*) | ||||||
|  |     intros. | ||||||
|  |     destruct (In_split a l') as (l'1,(l'2,H6)). | ||||||
|  |     rewrite <- H. | ||||||
|  |     subst l. | ||||||
|  |     apply in_or_app; right; red; auto. | ||||||
|  |     apply perm_trans with (l'1++l'2). | ||||||
|  |     apply (H0 _ _ _ _ H3 H6). | ||||||
|  |     apply (H2 _ _ _ _ H6 H4). | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_cons_inv l l' a : | ||||||
|  |  Permutation (a::l) (a::l') -> Permutation l l'. | ||||||
|  | Proof. | ||||||
|  |   intro H; exact (Permutation_app_inv [] l [] l' a H). | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_cons_app_inv l l1 l2 a : | ||||||
|  |  Permutation (a :: l) (l1 ++ a :: l2) -> Permutation l (l1 ++ l2). | ||||||
|  | Proof. | ||||||
|  |   intro H; exact (Permutation_app_inv [] l l1 l2 a H). | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_app_inv_l : forall l l1 l2, | ||||||
|  |  Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2. | ||||||
|  | Proof. | ||||||
|  |   induction l; simpl; auto. | ||||||
|  |   intros. | ||||||
|  |   apply IHl. | ||||||
|  |   apply Permutation_cons_inv with a; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem Permutation_app_inv_r : forall l l1 l2, | ||||||
|  |  Permutation (l1 ++ l) (l2 ++ l) -> Permutation l1 l2. | ||||||
|  | Proof. | ||||||
|  |   induction l. | ||||||
|  |   intros l1 l2; do 2 rewrite app_nil_r; auto. | ||||||
|  |   intros. | ||||||
|  |   apply IHl. | ||||||
|  |   apply Permutation_app_inv with a; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_length_1_inv: forall a l, Permutation [a] l -> l = [a]. | ||||||
|  | Proof. | ||||||
|  |   intros a l H; remember [a] as m in H. | ||||||
|  |   induction H; try (injection Heqm as -> ->; clear Heqm); | ||||||
|  |     discriminate || auto. | ||||||
|  |   apply Permutation_nil in H as ->; trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_length_1: forall a b, Permutation [a] [b] -> a = b. | ||||||
|  | Proof. | ||||||
|  |   intros a b H. | ||||||
|  |   apply Permutation_length_1_inv in H; injection H as ->; trivial. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_length_2_inv : | ||||||
|  |   forall a1 a2 l, Permutation [a1;a2] l -> l = [a1;a2] \/ l = [a2;a1]. | ||||||
|  | Proof. | ||||||
|  |   intros a1 a2 l H; remember [a1;a2] as m in H. | ||||||
|  |   revert a1 a2 Heqm. | ||||||
|  |   induction H; intros; try (injection Heqm; intros; subst; clear Heqm); | ||||||
|  |     discriminate || (try tauto). | ||||||
|  |   apply Permutation_length_1_inv in H as ->; left; auto. | ||||||
|  |   apply IHPermutation1 in Heqm as [H1|H1]; apply IHPermutation2 in H1 as (); | ||||||
|  |     auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_length_2 : | ||||||
|  |   forall a1 a2 b1 b2, Permutation [a1;a2] [b1;b2] -> | ||||||
|  |     a1 = b1 /\ a2 = b2 \/ a1 = b2 /\ a2 = b1. | ||||||
|  | Proof. | ||||||
|  |   intros a1 b1 a2 b2 H. | ||||||
|  |   apply Permutation_length_2_inv in H as [H|H]; injection H as -> ->; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Let in_middle l l1 l2 (a:A) : l = l1 ++ a :: l2 -> | ||||||
|  |  forall x, In x l <-> a = x \/ In x (l1++l2). | ||||||
|  | Proof. | ||||||
|  |  intros; subst; rewrite !in_app_iff; simpl. tauto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma NoDup_cardinal_incl (l l' : list A) : NoDup l -> NoDup l' -> | ||||||
|  |   length l = length l' -> incl l l' -> incl l' l. | ||||||
|  | Proof. | ||||||
|  |  intros N. revert l'. induction N as [|a l Hal Hl IH]. | ||||||
|  |  - destruct l'; now auto. | ||||||
|  |  - intros l' Hl' E H x Hx. | ||||||
|  |    assert (Ha : In a l') by (apply H; simpl; auto). | ||||||
|  |    destruct (in_split _ _ Ha) as (l1 & l2 & H12). clear Ha. | ||||||
|  |    rewrite in_middle in Hx; eauto. | ||||||
|  |    destruct Hx as [Hx|Hx]; [left|right]; auto. | ||||||
|  |    apply (IH (l1++l2)); auto. | ||||||
|  |    * apply NoDup_remove_1 with a; rewrite <- H12; auto. | ||||||
|  |    * apply eq_add_S. | ||||||
|  |      simpl in E; rewrite E, H12, !app_length; simpl; auto with arith. | ||||||
|  |    * intros y Hy. assert (Hy' : In y l') by (apply H; simpl; auto). | ||||||
|  |      rewrite in_middle in Hy'; eauto. | ||||||
|  |      destruct Hy'; auto. subst y; intuition. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma NoDup_Permutation l l' : NoDup l -> NoDup l' -> | ||||||
|  |   (forall x:A, In x l <-> In x l') -> Permutation l l'. | ||||||
|  | Proof. | ||||||
|  |  intros N. revert l'. induction N as [|a l Hal Hl IH]. | ||||||
|  |  - destruct l'; simpl; auto. | ||||||
|  |    intros Hl' H. exfalso. rewrite (H a); auto. | ||||||
|  |  - intros l' Hl' H. | ||||||
|  |    assert (Ha : In a l') by (apply H; simpl; auto). | ||||||
|  |    destruct (In_split _ _ Ha) as (l1 & l2 & H12). | ||||||
|  |    rewrite H12. | ||||||
|  |    apply Permutation_cons_app. | ||||||
|  |    apply IH; auto. | ||||||
|  |    * apply NoDup_remove_1 with a; rewrite <- H12; auto. | ||||||
|  |    * intro x. split; intros Hx. | ||||||
|  |      + assert (Hx' : In x l') by (apply H; simpl; auto). | ||||||
|  |        rewrite in_middle in Hx'; eauto. | ||||||
|  |        destruct Hx'; auto. subst; intuition. | ||||||
|  |      + assert (Hx' : In x l') by (rewrite (in_middle l1 l2 a); eauto). | ||||||
|  |        rewrite <- H in Hx'. destruct Hx'; auto. | ||||||
|  |        subst. destruct (NoDup_remove_2 _ _ _ Hl' Hx). | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma NoDup_Permutation_bis l l' : NoDup l -> NoDup l' -> | ||||||
|  |   length l = length l' -> incl l l' -> Permutation l l'. | ||||||
|  | Proof. | ||||||
|  |  intros. apply NoDup_Permutation; auto. | ||||||
|  |  split; auto. apply NoDup_cardinal_incl; auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_NoDup l l' : Permutation l l' -> NoDup l -> NoDup l'. | ||||||
|  | Proof. | ||||||
|  |  induction 1; auto. | ||||||
|  |  * inversion_clear 1; constructor; eauto using Permutation_in. | ||||||
|  |  * inversion_clear 1 as [|? ? H1 H2]. inversion_clear H2; simpl in *. | ||||||
|  |    constructor. simpl; intuition. constructor; intuition. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Global Instance Permutation_NoDup' : | ||||||
|  |  Proper (@Permutation A ==> iff) (@NoDup A) | 10. | ||||||
|  | Proof. | ||||||
|  |   repeat red; eauto using Permutation_NoDup. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Permutation_properties. | ||||||
|  |  | ||||||
|  | Section Permutation_map. | ||||||
|  |  | ||||||
|  | Variable A B : Type. | ||||||
|  | Variable f : A -> B. | ||||||
|  |  | ||||||
|  | Lemma Permutation_map l l' : | ||||||
|  |   Permutation l l' -> Permutation (map f l) (map f l'). | ||||||
|  | Proof. | ||||||
|  |  induction 1; simpl; eauto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Global Instance Permutation_map' : | ||||||
|  |   Proper (@Permutation A ==> @Permutation B) (map f) | 10. | ||||||
|  | Proof. | ||||||
|  |   exact Permutation_map. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Permutation_map. | ||||||
|  |  | ||||||
|  | Section Injection. | ||||||
|  |  | ||||||
|  | Definition injective {A B} (f : A->B) := | ||||||
|  |  forall x y, f x = f y -> x = y. | ||||||
|  |  | ||||||
|  | Lemma injective_map_NoDup {A B} (f:A->B) (l:list A) : | ||||||
|  |  injective f -> NoDup l -> NoDup (map f l). | ||||||
|  | Proof. | ||||||
|  |  intros Hf. induction 1 as [|x l Hx Hl IH]; simpl; constructor; trivial. | ||||||
|  |  rewrite in_map_iff. intros (y & Hy & Hy'). apply Hf in Hy. now subst. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma injective_bounded_surjective n f : | ||||||
|  |  injective f -> | ||||||
|  |  (forall x, x < n -> f x < n) -> | ||||||
|  |  (forall y, y < n -> exists x, x < n /\ f x = y). | ||||||
|  | Proof. | ||||||
|  |  intros Hf H. | ||||||
|  |  set (l := seq 0 n). | ||||||
|  |  assert (P : incl (map f l) l). | ||||||
|  |  { intros x. rewrite in_map_iff. intros (y & <- & Hy'). | ||||||
|  |    unfold l in *. rewrite in_seq in *. simpl in *. | ||||||
|  |    destruct Hy' as (_,Hy'). auto with arith. } | ||||||
|  |  assert (P' : incl l (map f l)). | ||||||
|  |  { unfold l. | ||||||
|  |    apply NoDup_cardinal_incl; auto using injective_map_NoDup, seq_NoDup. | ||||||
|  |    now rewrite map_length. } | ||||||
|  |  intros x Hx. | ||||||
|  |  assert (Hx' : In x l) by (unfold l; rewrite in_seq; auto with arith). | ||||||
|  |  apply P' in Hx'. | ||||||
|  |  rewrite in_map_iff in Hx'. destruct Hx' as (y & Hy & Hy'). | ||||||
|  |  exists y; split; auto. unfold l in *; rewrite in_seq in Hy'. | ||||||
|  |  destruct Hy'; auto with arith. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma nat_bijection_Permutation n f : | ||||||
|  |  injective f -> (forall x, x < n -> f x < n) -> | ||||||
|  |  let l := seq 0 n in Permutation (map f l) l. | ||||||
|  | Proof. | ||||||
|  |  intros Hf BD. | ||||||
|  |  apply NoDup_Permutation_bis; auto using injective_map_NoDup, seq_NoDup. | ||||||
|  |  * now rewrite map_length. | ||||||
|  |  * intros x. rewrite in_map_iff. intros (y & <- & Hy'). | ||||||
|  |    rewrite in_seq in *. simpl in *. | ||||||
|  |    destruct Hy' as (_,Hy'). auto with arith. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Injection. | ||||||
|  |  | ||||||
|  | Section Permutation_alt. | ||||||
|  | Variable A:Type. | ||||||
|  | Implicit Type a : A. | ||||||
|  | Implicit Type l : list A. | ||||||
|  |  | ||||||
|  | (** Alternative characterization of permutation | ||||||
|  |     via [nth_error] and [nth] *) | ||||||
|  |  | ||||||
|  | Let adapt f n := | ||||||
|  |  let m := f (S n) in if le_lt_dec m (f 0) then m else pred m. | ||||||
|  |  | ||||||
|  | Let adapt_injective f : injective f -> injective (adapt f). | ||||||
|  | Proof. | ||||||
|  |  unfold adapt. intros Hf x y EQ. | ||||||
|  |  destruct le_lt_dec as [LE|LT]; destruct le_lt_dec as [LE'|LT']. | ||||||
|  |  - now apply eq_add_S, Hf. | ||||||
|  |  - apply Lt.le_lt_or_eq in LE. | ||||||
|  |    destruct LE as [LT|EQ']; [|now apply Hf in EQ']. | ||||||
|  |    unfold lt in LT. rewrite EQ in LT. | ||||||
|  |    rewrite <- (Lt.S_pred _ _ LT') in LT. | ||||||
|  |    elim (Lt.lt_not_le _ _ LT' LT). | ||||||
|  |  - apply Lt.le_lt_or_eq in LE'. | ||||||
|  |    destruct LE' as [LT'|EQ']; [|now apply Hf in EQ']. | ||||||
|  |    unfold lt in LT'. rewrite <- EQ in LT'. | ||||||
|  |    rewrite <- (Lt.S_pred _ _ LT) in LT'. | ||||||
|  |    elim (Lt.lt_not_le _ _ LT LT'). | ||||||
|  |  - apply eq_add_S, Hf. | ||||||
|  |    now rewrite (Lt.S_pred _ _ LT), (Lt.S_pred _ _ LT'), EQ. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Let adapt_ok a l1 l2 f : injective f -> length l1 = f 0 -> | ||||||
|  |  forall n, nth_error (l1++a::l2) (f (S n)) = nth_error (l1++l2) (adapt f n). | ||||||
|  | Proof. | ||||||
|  |  unfold adapt. intros Hf E n. | ||||||
|  |  destruct le_lt_dec as [LE|LT]. | ||||||
|  |  - apply Lt.le_lt_or_eq in LE. | ||||||
|  |    destruct LE as [LT|EQ]; [|now apply Hf in EQ]. | ||||||
|  |    rewrite <- E in LT. | ||||||
|  |    rewrite 2 nth_error_app1; auto. | ||||||
|  |  - rewrite (Lt.S_pred _ _ LT) at 1. | ||||||
|  |    rewrite <- E, (Lt.S_pred _ _ LT) in LT. | ||||||
|  |    rewrite 2 nth_error_app2; auto with arith. | ||||||
|  |    rewrite <- Minus.minus_Sn_m; auto with arith. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_nth_error l l' : | ||||||
|  |  Permutation l l' <-> | ||||||
|  |   (length l = length l' /\ | ||||||
|  |    exists f:nat->nat, | ||||||
|  |     injective f /\ forall n, nth_error l' n = nth_error l (f n)). | ||||||
|  | Proof. | ||||||
|  |  split. | ||||||
|  |  { intros P. | ||||||
|  |    split; [now apply Permutation_length|]. | ||||||
|  |    induction P. | ||||||
|  |    - exists (fun n => n). | ||||||
|  |      split; try red; auto. | ||||||
|  |    - destruct IHP as (f & Hf & Hf'). | ||||||
|  |      exists (fun n => match n with O => O | S n => S (f n) end). | ||||||
|  |      split; try red. | ||||||
|  |      * intros [|y] [|z]; simpl; now auto. | ||||||
|  |      * intros [|n]; simpl; auto. | ||||||
|  |    - exists (fun n => match n with 0 => 1 | 1 => 0 | n => n end). | ||||||
|  |      split; try red. | ||||||
|  |      * intros [|[|z]] [|[|t]]; simpl; now auto. | ||||||
|  |      * intros [|[|n]]; simpl; auto. | ||||||
|  |    - destruct IHP1 as (f & Hf & Hf'). | ||||||
|  |      destruct IHP2 as (g & Hg & Hg'). | ||||||
|  |      exists (fun n => f (g n)). | ||||||
|  |      split; try red. | ||||||
|  |      * auto. | ||||||
|  |      * intros n. rewrite <- Hf'; auto. } | ||||||
|  |  { revert l. induction l'. | ||||||
|  |    - intros [|l] (E & _); now auto. | ||||||
|  |    - intros l (E & f & Hf & Hf'). | ||||||
|  |      simpl in E. | ||||||
|  |      assert (Ha : nth_error l (f 0) = Some a) | ||||||
|  |       by (symmetry; apply (Hf' 0)). | ||||||
|  |      destruct (nth_error_split l (f 0) Ha) as (l1 & l2 & L12 & L1). | ||||||
|  |      rewrite L12. rewrite <- Permutation_middle. constructor. | ||||||
|  |      apply IHl'; split; [|exists (adapt f); split]. | ||||||
|  |      * revert E. rewrite L12, !app_length. simpl. | ||||||
|  |        rewrite <- plus_n_Sm. now injection 1. | ||||||
|  |      * now apply adapt_injective. | ||||||
|  |      * intro n. rewrite <- (adapt_ok a), <- L12; auto. | ||||||
|  |        apply (Hf' (S n)). } | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_nth_error_bis l l' : | ||||||
|  |  Permutation l l' <-> | ||||||
|  |   exists f:nat->nat, | ||||||
|  |     injective f /\ | ||||||
|  |     (forall n, n < length l -> f n < length l) /\ | ||||||
|  |     (forall n, nth_error l' n = nth_error l (f n)). | ||||||
|  | Proof. | ||||||
|  |  rewrite Permutation_nth_error; split. | ||||||
|  |  - intros (E & f & Hf & Hf'). | ||||||
|  |    exists f. do 2 (split; trivial). | ||||||
|  |    intros n Hn. | ||||||
|  |    destruct (Lt.le_or_lt (length l) (f n)) as [LE|LT]; trivial. | ||||||
|  |    rewrite <- nth_error_None, <- Hf', nth_error_None, <- E in LE. | ||||||
|  |    elim (Lt.lt_not_le _ _ Hn LE). | ||||||
|  |  - intros (f & Hf & Hf2 & Hf3); split; [|exists f; auto]. | ||||||
|  |    assert (H : length l' <= length l') by auto with arith. | ||||||
|  |    rewrite <- nth_error_None, Hf3, nth_error_None in H. | ||||||
|  |    destruct (Lt.le_or_lt (length l) (length l')) as [LE|LT]; | ||||||
|  |     [|apply Hf2 in LT; elim (Lt.lt_not_le _ _ LT H)]. | ||||||
|  |    apply Lt.le_lt_or_eq in LE. destruct LE as [LT|EQ]; trivial. | ||||||
|  |    rewrite <- nth_error_Some, Hf3, nth_error_Some in LT. | ||||||
|  |    destruct (injective_bounded_surjective Hf Hf2 LT) as (y & Hy & Hy'). | ||||||
|  |    apply Hf in Hy'. subst y. elim (Lt.lt_irrefl _ Hy). | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma Permutation_nth l l' d : | ||||||
|  |  Permutation l l' <-> | ||||||
|  |   (let n := length l in | ||||||
|  |    length l' = n /\ | ||||||
|  |    exists f:nat->nat, | ||||||
|  |     (forall x, x < n -> f x < n) /\ | ||||||
|  |     (forall x y, x < n -> y < n -> f x = f y -> x = y) /\ | ||||||
|  |     (forall x, x < n -> nth x l' d = nth (f x) l d)). | ||||||
|  | Proof. | ||||||
|  |  split. | ||||||
|  |  - intros H. | ||||||
|  |    assert (E := Permutation_length H). | ||||||
|  |    split; auto. | ||||||
|  |    apply Permutation_nth_error_bis in H. | ||||||
|  |    destruct H as (f & Hf & Hf2 & Hf3). | ||||||
|  |    exists f. split; [|split]; auto. | ||||||
|  |    intros n Hn. rewrite <- 2 nth_default_eq. unfold nth_default. | ||||||
|  |     now rewrite Hf3. | ||||||
|  |  - intros (E & f & Hf1 & Hf2 & Hf3). | ||||||
|  |    rewrite Permutation_nth_error. | ||||||
|  |    split; auto. | ||||||
|  |    exists (fun n => if le_lt_dec (length l) n then n else f n). | ||||||
|  |    split. | ||||||
|  |    * intros x y. | ||||||
|  |      destruct le_lt_dec as [LE|LT]; | ||||||
|  |       destruct le_lt_dec as [LE'|LT']; auto. | ||||||
|  |      + apply Hf1 in LT'. intros ->. | ||||||
|  |        elim (Lt.lt_irrefl (f y)). eapply Lt.lt_le_trans; eauto. | ||||||
|  |      + apply Hf1 in LT. intros <-. | ||||||
|  |        elim (Lt.lt_irrefl (f x)). eapply Lt.lt_le_trans; eauto. | ||||||
|  |    * intros n. | ||||||
|  |      destruct le_lt_dec as [LE|LT]. | ||||||
|  |      + assert (LE' : length l' <= n) by (now rewrite E). | ||||||
|  |        rewrite <- nth_error_None in LE, LE'. congruence. | ||||||
|  |      + assert (LT' : n < length l') by (now rewrite E). | ||||||
|  |        specialize (Hf3 n LT). rewrite <- 2 nth_default_eq in Hf3. | ||||||
|  |        unfold nth_default in Hf3. | ||||||
|  |        apply Hf1 in LT. | ||||||
|  |        rewrite <- nth_error_Some in LT, LT'. | ||||||
|  |        do 2 destruct nth_error; congruence. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Permutation_alt. | ||||||
|  |  | ||||||
|  | (* begin hide *) | ||||||
|  | Notation Permutation_app_swap := Permutation_app_comm (only parsing). | ||||||
|  | (* end hide *) | ||||||
							
								
								
									
										875
									
								
								samples/coq/Poly.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										875
									
								
								samples/coq/Poly.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,875 @@ | |||||||
|  | Require Export Lists. | ||||||
|  | Require Export Basics. | ||||||
|  |  | ||||||
|  | Import Playground1. | ||||||
|  |  | ||||||
|  | Inductive list (X : Type) : Type := | ||||||
|  | 	| nil : list X | ||||||
|  | 	| cons : X -> list X -> list X. | ||||||
|  |  | ||||||
|  | Fixpoint length (X:Type) (l:list X) : nat := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => O | ||||||
|  | 		| cons h t => S (length X t) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint app (X : Type) (l1 l2 : list X) | ||||||
|  | 										: (list X) := | ||||||
|  | 	match l1 with | ||||||
|  | 		| nil => l2 | ||||||
|  | 		| cons h t => cons X h (app X t l2) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint snoc (X:Type) (l:list X) (v:X) : (list X) := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => cons X v (nil X) | ||||||
|  | 		| cons h t => cons X h (snoc X t v) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint rev (X:Type) (l:list X) : list X := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => nil X | ||||||
|  | 		| cons h t => snoc X (rev X t) h | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Implicit Arguments nil [[X]]. | ||||||
|  | Implicit Arguments cons [[X]]. | ||||||
|  | Implicit Arguments length [[X]]. | ||||||
|  | Implicit Arguments app [[X]]. | ||||||
|  | Implicit Arguments rev [[X]]. | ||||||
|  | Implicit Arguments snoc [[X]]. | ||||||
|  |  | ||||||
|  | Definition list123 := cons 1 (cons 2 (cons 3 (nil))). | ||||||
|  |  | ||||||
|  | Notation "x :: y" := (cons x y) (at level 60, right associativity). | ||||||
|  | Notation "[]" := nil. | ||||||
|  | Notation "[ x , .. , y ]" := (cons x .. (cons y []) ..). | ||||||
|  | Notation "x ++ y" := (app x y) (at level 60, right associativity). | ||||||
|  |  | ||||||
|  | Fixpoint repeat (X : Type) (n : X) (count : nat) : list X := | ||||||
|  | 	match count with | ||||||
|  | 		| O => nil | ||||||
|  | 		| S count' => n :: (repeat _ n count') | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example test_repeat1: | ||||||
|  | 	repeat bool true (S (S O)) = [true, true]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem nil_app : forall X:Type, forall l:list X, | ||||||
|  | 	app [] l = l. | ||||||
|  | Proof. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem rev_snoc : forall X : Type, | ||||||
|  | 									 forall v : X, | ||||||
|  | 									 forall s : list X, | ||||||
|  | 	rev (snoc s v) = v :: (rev s). | ||||||
|  | Proof. | ||||||
|  | 	intros X v s. | ||||||
|  | 	induction s. | ||||||
|  | 		reflexivity. | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> IHs. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Theorem snoc_with_append : forall X : Type, | ||||||
|  | 													 forall l1 l2 : list X, | ||||||
|  | 													 forall v : X, | ||||||
|  | 	snoc (l1 ++ l2) v = l1 ++ (snoc l2 v). | ||||||
|  | Proof. | ||||||
|  | 	intros X l1 l2 v. | ||||||
|  | 	induction l1. | ||||||
|  | 		reflexivity. | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite -> IHl1. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Inductive prod (X Y : Type) : Type := | ||||||
|  | 	pair : X -> Y -> prod X Y. | ||||||
|  |  | ||||||
|  | Implicit Arguments pair [X Y]. | ||||||
|  |  | ||||||
|  | Notation "( x , y )" := (pair x y). | ||||||
|  | Notation "X * Y" := (prod X Y) : type_scope. | ||||||
|  |  | ||||||
|  | Definition fst (X Y : Type) (p : X * Y) : X := | ||||||
|  | 	match p with (x,y) => x end. | ||||||
|  | Definition snd (X Y : Type) (p : X * Y) : Y := | ||||||
|  | 	match p with (x,y) => y end. | ||||||
|  |  | ||||||
|  | Fixpoint combine (X Y : Type) (lx : list X) (ly : list Y) | ||||||
|  | 			: list (X * Y) := | ||||||
|  | 	match lx, ly with | ||||||
|  | 		| [], _ => [] | ||||||
|  | 		| _,[] => [] | ||||||
|  | 		| x::tx, y::ty => (x,y) :: (combine _ _ tx ty) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Implicit Arguments combine [X Y]. | ||||||
|  |  | ||||||
|  | Fixpoint split {X Y: Type} (s : list (X * Y)) : (list X)*(list Y) := | ||||||
|  | 	match s with | ||||||
|  | 		| nil => (nil, nil) | ||||||
|  | 		| (x,y) :: tp => match split tp with | ||||||
|  | 											| (lx, ly) => (x :: lx, y :: ly) | ||||||
|  | 										 end | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Inductive option (X : Type) : Type := | ||||||
|  | 	| Some : X -> option X | ||||||
|  | 	| None : option X. | ||||||
|  |  | ||||||
|  | Implicit Arguments Some [X]. | ||||||
|  | Implicit Arguments None [X]. | ||||||
|  |  | ||||||
|  | Fixpoint index (X : Type) (n : nat) | ||||||
|  | 							 (l : list X) : option X := | ||||||
|  | 	match n with | ||||||
|  | 		| O => match l with | ||||||
|  | 								| nil => None | ||||||
|  | 								| x :: xs => Some x | ||||||
|  | 					 end | ||||||
|  | 		| S n' => match l with | ||||||
|  | 									| nil => None | ||||||
|  | 									| x :: xs => index X n' xs | ||||||
|  | 							end | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Definition hd_opt (X : Type) (l : list X) : option X := | ||||||
|  | 		match l with | ||||||
|  | 			| nil => None | ||||||
|  | 			| x :: xs => Some x | ||||||
|  | 		end. | ||||||
|  |  | ||||||
|  | Implicit Arguments hd_opt [X]. | ||||||
|  |  | ||||||
|  | Example test_hd_opt1 : hd_opt [S O, S (S O)] = Some (S O). | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | Example test_hd_opt2 : hd_opt [[S O], [S (S O)]] = Some [S O]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Definition plus3 := plus (S (S (S O))). | ||||||
|  |  | ||||||
|  | Definition prod_curry {X Y Z : Type} | ||||||
|  | 		(f : X * Y -> Z) (x : X) (y : Y) : Z := f (x,y). | ||||||
|  |  | ||||||
|  | Definition prod_uncurry {X Y Z : Type} | ||||||
|  | 	(f : X -> Y -> Z) (p : X * Y) : Z := | ||||||
|  | 	f (fst X Y p) (snd X Y p). | ||||||
|  |  | ||||||
|  | Theorem uncurry_uncurry : forall (X Y Z : Type) (f : X -> Y -> Z) x y, | ||||||
|  | 				prod_curry (prod_uncurry f) x y = f x y. | ||||||
|  | Proof. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem curry_uncurry : forall (X Y Z : Type) (f : (X * Y) -> Z) | ||||||
|  | 	(p : X * Y), | ||||||
|  | 		prod_uncurry (prod_curry f) p = f p. | ||||||
|  | Proof. | ||||||
|  | 	destruct p. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Fixpoint filter (X : Type) (test : X -> bool) (l:list X) | ||||||
|  | 				: (list X) := | ||||||
|  | 		match l with | ||||||
|  | 			| [] => [] | ||||||
|  | 		  | h :: t => if test h then h :: (filter _ test t) | ||||||
|  | 									else filter _ test t | ||||||
|  | 		end. | ||||||
|  |  | ||||||
|  | Definition countoddmembers' (l:list nat) : nat := | ||||||
|  | 	length (filter _ oddb l). | ||||||
|  |  | ||||||
|  | Definition partition (X : Type) (test : X -> bool) (l : list X) | ||||||
|  | 							: list X * list X := | ||||||
|  | 	(filter _ test l, filter _ (fun el => negb (test el)) l). | ||||||
|  |  | ||||||
|  | Example test_partition1: partition _ oddb [S O, S (S O), S (S (S O)), S (S (S (S O))), S (S (S (S (S O))))] = ([S O, S (S (S O)), S (S (S (S (S O))))], [S (S O), S (S (S (S O)))]). | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Fixpoint map {X Y : Type} (f : X -> Y) (l : list X) : (list Y ) := | ||||||
|  | 		match l with | ||||||
|  | 			| [] => [] | ||||||
|  | 			| h :: t => (f h) :: (map f t) | ||||||
|  | 		end. | ||||||
|  |  | ||||||
|  | Example test_map1: map (plus (S (S (S O)))) [S (S O), O, S (S O)] = [S (S (S (S (S O)))), S (S (S O)), S (S (S (S (S O))))]. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  |  Theorem map_rev_1 : forall (X Y: Type) (f: X -> Y) (l : list X) (x : X), | ||||||
|  |  		map f (snoc l x) = snoc (map f l) (f x). | ||||||
|  | Proof. | ||||||
|  | 	intros X Y f l x. | ||||||
|  | 	induction l. | ||||||
|  | 	reflexivity. | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite -> IHl. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem map_rev : forall (X Y : Type) (f : X -> Y) (l : list X), | ||||||
|  | 				map f (rev l) = rev (map f l). | ||||||
|  | Proof. | ||||||
|  | 	intros X Y f l. | ||||||
|  | 	induction l. | ||||||
|  | 		reflexivity. | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite <- IHl. | ||||||
|  | 		rewrite -> map_rev_1. | ||||||
|  | 		reflexivity. | ||||||
|  | 		Qed. | ||||||
|  |  | ||||||
|  | Fixpoint flat_map {X Y : Type} (f : X -> list Y) (l : list X) | ||||||
|  | 			: (list Y) := | ||||||
|  | 	match l with | ||||||
|  | 		| [] => [] | ||||||
|  | 		| x :: xs => (f x) ++ (flat_map f xs) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Definition map_option {X Y : Type} (f : X -> Y) (xo : option X) | ||||||
|  | 		: option Y := | ||||||
|  | 	match xo with | ||||||
|  | 		| None => None | ||||||
|  | 		| Some x => Some (f x) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint fold {X Y: Type} (f: X -> Y -> Y) (l:list X) (b:Y) : Y := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => b | ||||||
|  | 		| h :: t => f h (fold f t b) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Example fold_example : fold andb [true, true, false, true] true = false. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Definition constfun {X : Type} (x: X) : nat -> X := | ||||||
|  | 	fun (k:nat) => x. | ||||||
|  |  | ||||||
|  | Definition ftrue := constfun true. | ||||||
|  | Example constfun_example : ftrue O = true. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Definition override {X : Type} (f: nat -> X) (k:nat) (x:X) : nat->X := | ||||||
|  | 	fun (k':nat) => if beq_nat k k' then x else f k'. | ||||||
|  |  | ||||||
|  | Definition fmostlytrue := override (override ftrue (S O) false) (S (S (S O))) false. | ||||||
|  |  | ||||||
|  | Example override_example1 : fmostlytrue O = true. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | Example override_example2 : fmostlytrue (S O) = false. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | Example override_example3 : fmostlytrue (S (S O)) = true. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  | Example override_example4 : fmostlytrue (S (S (S O))) = false. | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem override_example : forall (b: bool), | ||||||
|  | 	(override (constfun b) (S (S (S O))) true) (S (S O)) = b. | ||||||
|  | Proof. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem unfold_example_bad : forall m n, | ||||||
|  | 	(S (S (S O))) + n = m -> | ||||||
|  | 	plus3 n = m. | ||||||
|  | Proof. | ||||||
|  | 	intros m n H. | ||||||
|  | 	unfold plus3. | ||||||
|  | 	rewrite -> H. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem override_eq : forall {X : Type} x k (f : nat -> X), | ||||||
|  | 	(override f k x) k = x. | ||||||
|  | Proof. | ||||||
|  | 	intros X x k f. | ||||||
|  | 	unfold override. | ||||||
|  | 	rewrite <- beq_nat_refl. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem override_neq : forall {X : Type} x1 x2 k1 k2 (f : nat->X), | ||||||
|  | 	f k1 = x1 -> | ||||||
|  | 		beq_nat k2 k1 = false -> | ||||||
|  | 			(override f k2 x2) k1 = x1. | ||||||
|  | Proof. | ||||||
|  | 	intros X x1 x2 k1 k2 f eq1 eq2. | ||||||
|  | 	unfold override. | ||||||
|  | 	rewrite -> eq2. | ||||||
|  | 	rewrite -> eq1. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem eq_add_S : forall (n m : nat), | ||||||
|  | 	S n = S m -> | ||||||
|  | 		n = m. | ||||||
|  | Proof. | ||||||
|  | 	intros n m eq. | ||||||
|  | 	inversion eq. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem silly4 : forall (n m : nat), | ||||||
|  | 	[n] = [m] -> | ||||||
|  | 		n = m. | ||||||
|  | Proof. | ||||||
|  | 	intros n o eq. | ||||||
|  | 	inversion eq. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem silly5 : forall (n m o : nat), | ||||||
|  | 	[n,m] = [o,o] -> | ||||||
|  | 		[n] = [m]. | ||||||
|  | Proof. | ||||||
|  | 	intros n m o eq. | ||||||
|  | 	inversion eq. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem sillyex1 : forall (X : Type) (x y z : X) (l j : list X), | ||||||
|  | 	x :: y :: l = z :: j -> | ||||||
|  | 		y :: l = x :: j -> | ||||||
|  | 			x = y. | ||||||
|  | Proof. | ||||||
|  | 	intros X x y z l j. | ||||||
|  | 	intros eq1 eq2. | ||||||
|  | 	inversion eq1. | ||||||
|  | 	inversion eq2. | ||||||
|  | 	symmetry. | ||||||
|  | 	rewrite -> H0. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem silly6 : forall (n : nat), | ||||||
|  | 	S n = O -> | ||||||
|  | 		(S (S O)) + (S (S O)) = (S (S (S (S (S O))))). | ||||||
|  | Proof. | ||||||
|  | 	intros n contra. | ||||||
|  | 	inversion contra. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem silly7 : forall (n m : nat), | ||||||
|  | 				false = true -> | ||||||
|  | 					[n] = [m]. | ||||||
|  | Proof. | ||||||
|  | 	intros n m contra. | ||||||
|  | 	inversion contra. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem sillyex2 : forall (X : Type) (x y z : X) (l j : list X), | ||||||
|  | 	x :: y :: l = [] -> | ||||||
|  | 		y :: l = z :: j -> | ||||||
|  | 			x = z. | ||||||
|  | Proof. | ||||||
|  | 	intros X x y z l j contra. | ||||||
|  | 	inversion contra. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem beq_nat_eq : forall n m, | ||||||
|  | 	true = beq_nat n m -> n = m. | ||||||
|  | Proof. | ||||||
|  | 	intros n. induction n as [| n']. | ||||||
|  | 	Case "n = O". | ||||||
|  | 		intros m. destruct m as [| m']. | ||||||
|  | 		SCase "m = 0". reflexivity. | ||||||
|  | 		SCase "m = S m'". simpl. intros contra. inversion contra. | ||||||
|  | 	Case "n = S n'". | ||||||
|  | 		intros m. destruct m as [| m']. | ||||||
|  | 		SCase "m = 0". simpl. intros contra. inversion contra. | ||||||
|  | 		SCase "m = S m'". simpl. intros H. | ||||||
|  | 			assert(n' = m') as Hl. | ||||||
|  | 				SSCase "Proof of assertion". apply IHn'. apply H. | ||||||
|  | 			rewrite -> Hl. reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem beq_nat_eq' : forall m n, | ||||||
|  | 				beq_nat n m = true -> n = m. | ||||||
|  | Proof. | ||||||
|  | 	intros m. induction m as [| m']. | ||||||
|  | 	Case "m = O". | ||||||
|  | 		destruct n. | ||||||
|  | 		SCase "n = O". | ||||||
|  | 			reflexivity. | ||||||
|  | 		SCase "n = S n'". | ||||||
|  | 			simpl. intros contra. inversion contra. | ||||||
|  | 	Case "m = S m'". | ||||||
|  | 		simpl. | ||||||
|  | 		destruct n. | ||||||
|  | 		SCase "n = O". | ||||||
|  | 			simpl. intros contra. inversion contra. | ||||||
|  | 		SCase "n = S n'". | ||||||
|  | 			simpl. intros H. | ||||||
|  | 			assert (n = m') as Hl. | ||||||
|  | 				apply IHm'. | ||||||
|  | 				apply H. | ||||||
|  | 			rewrite -> Hl. | ||||||
|  | 			reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem length_snoc' : forall (X : Type) (v : X) | ||||||
|  | (l : list X) (n : nat), | ||||||
|  | 	length l = n -> | ||||||
|  | 	length (snoc l v) = S n. | ||||||
|  | 	Proof. | ||||||
|  | 	intros X v l. induction l as [| v' l']. | ||||||
|  | 	Case "l = []". intros n eq. rewrite <- eq. reflexivity. | ||||||
|  | 	Case "l = v' :: l'". intros n eq. simpl. destruct n as [| n']. | ||||||
|  | 	SCase "n = 0". inversion eq. | ||||||
|  | 	SCase "n = S n'". | ||||||
|  | 	assert (length (snoc l' v) = S n'). | ||||||
|  | 	SSCase "Proof of assertion". apply IHl'. | ||||||
|  | 	inversion eq. reflexivity. | ||||||
|  | 	rewrite -> H. reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | 	Theorem beq_nat_O_l : forall n, | ||||||
|  | 	true = beq_nat O n -> O = n. | ||||||
|  | 	Proof. | ||||||
|  | 	intros n. destruct n. | ||||||
|  | 	reflexivity. | ||||||
|  | 	simpl. | ||||||
|  | 	intros contra. | ||||||
|  | 	inversion contra. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem beq_nat_O_r : forall n, | ||||||
|  | 	true = beq_nat n O -> O = n. | ||||||
|  | Proof. | ||||||
|  | 	intros n. | ||||||
|  | 	induction n. | ||||||
|  | 	Case "n = O". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "n = S n'". | ||||||
|  | 		simpl. | ||||||
|  | 		intros contra. | ||||||
|  | 		inversion contra. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem double_injective : forall n m, | ||||||
|  | 	double n = double m -> | ||||||
|  | 		n = m. | ||||||
|  | Proof. | ||||||
|  | 	intros n. induction n as [| n']. | ||||||
|  | 	Case "n = O". | ||||||
|  | 		simpl. intros m eq. | ||||||
|  | 		destruct m as [|m']. | ||||||
|  | 		SCase "m = O". reflexivity. | ||||||
|  | 		SCase "m = S m'". inversion eq. | ||||||
|  | 	Case "n = S n'". intros m eq. destruct m as [| m']. | ||||||
|  | 		SCase "m = O". inversion eq. | ||||||
|  | 		SCase "m = S m'". | ||||||
|  | 			assert(n' = m') as H. | ||||||
|  | 				SSCase "Proof of assertion". apply IHn'. inversion eq. reflexivity. | ||||||
|  | 			rewrite -> H. reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem silly3' : forall (n : nat), | ||||||
|  | 	(beq_nat n (S (S (S (S (S O))))) = true -> | ||||||
|  | 	 	beq_nat (S (S n)) (S (S (S (S (S (S (S O))))))) = true) -> | ||||||
|  | 		true = beq_nat n (S (S (S (S (S O))))) -> | ||||||
|  | 			true = beq_nat (S (S n)) (S (S (S (S (S (S (S O))))))). | ||||||
|  | Proof. | ||||||
|  | 	intros n eq H. | ||||||
|  | 	symmetry in H. | ||||||
|  | 	apply eq in H. | ||||||
|  | 	symmetry in H. | ||||||
|  | 	apply H. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem plus_n_n_injective : forall n m, | ||||||
|  | 					n + n = m + m -> | ||||||
|  | 						n = m. | ||||||
|  | Proof. | ||||||
|  | 	intros n. induction n as [| n']. | ||||||
|  | 	Case "n = O". | ||||||
|  | 		simpl. intros m. | ||||||
|  | 		destruct m. | ||||||
|  | 			SCase "m = O". | ||||||
|  | 			reflexivity. | ||||||
|  | 			SCase "m = S m'". | ||||||
|  | 			simpl. | ||||||
|  | 			intros contra. | ||||||
|  | 			inversion contra. | ||||||
|  | 	Case "n = S n". | ||||||
|  | 		intros m. | ||||||
|  | 		destruct m. | ||||||
|  | 			SCase "m = O". | ||||||
|  | 			intros contra. | ||||||
|  | 			inversion contra. | ||||||
|  | 			SCase "m = S m'". | ||||||
|  | 			intros eq. | ||||||
|  | 			inversion eq. | ||||||
|  | 			rewrite <- plus_n_Sm in H0. | ||||||
|  | 			rewrite <- plus_n_Sm in H0. | ||||||
|  | 			inversion H0. | ||||||
|  | 			apply IHn' in H1. | ||||||
|  | 			rewrite -> H1. | ||||||
|  | 			reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem override_shadow : forall {X : Type} x1 x2 k1 k2 (f : nat -> X), | ||||||
|  | 	(override (override f k1 x2) k1 x1) k2 = (override f k1 x1) k2. | ||||||
|  | Proof. | ||||||
|  | 	intros X x1 x2 k1 k2 f. | ||||||
|  | 	unfold override. | ||||||
|  | 	destruct (beq_nat k1 k2). | ||||||
|  | 	reflexivity. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem combine_split : forall (X : Type) (Y : Type) (l : list (X * Y)) (l1: list X) (l2: list Y), | ||||||
|  | 				split l = (l1, l2) -> combine l1 l2 = l. | ||||||
|  | Proof. | ||||||
|  | 	intros X Y l. | ||||||
|  | 	induction l as [| x y]. | ||||||
|  | 	Case "l = nil". | ||||||
|  | 		intros l1 l2. | ||||||
|  | 		intros eq. | ||||||
|  | 		simpl. | ||||||
|  | 		simpl in eq. | ||||||
|  | 		inversion eq. | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l = ::". | ||||||
|  | 		intros l1 l2. | ||||||
|  | 		simpl. | ||||||
|  | 		destruct x. | ||||||
|  | 		destruct (split y). | ||||||
|  | 		simpl. | ||||||
|  | 		destruct l1. | ||||||
|  | 		SCase "l1 = []". | ||||||
|  | 			simpl. | ||||||
|  | 			induction l2. | ||||||
|  | 			SSCase "l2 = []". | ||||||
|  | 				intros contra. | ||||||
|  | 				inversion contra. | ||||||
|  | 			SSCase "l2 = ::". | ||||||
|  | 				intros contra. | ||||||
|  | 				inversion contra. | ||||||
|  | 		SCase "l1 = ::". | ||||||
|  | 			induction l2. | ||||||
|  | 			SSCase "l2 = []". | ||||||
|  | 				simpl. | ||||||
|  | 				intros contra. | ||||||
|  | 				inversion contra. | ||||||
|  | 			SSCase "l2 = ::". | ||||||
|  | 				simpl. | ||||||
|  | 				intros eq. | ||||||
|  | 				inversion eq. | ||||||
|  | 				simpl. | ||||||
|  | 				rewrite IHy. | ||||||
|  | 				reflexivity. | ||||||
|  | 				simpl. | ||||||
|  | 				rewrite H1. | ||||||
|  | 				rewrite H3. | ||||||
|  | 				reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem split_combine : forall (X : Type) (Y : Type) (l1: list X) (l2: list Y), | ||||||
|  | 				length l1 = length l2 -> split (combine l1 l2) = (l1, l2). | ||||||
|  | Proof. | ||||||
|  | intros X Y. | ||||||
|  | intros l1. | ||||||
|  | induction l1. | ||||||
|  | simpl. | ||||||
|  | intros l2. | ||||||
|  | induction l2. | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | intros contra. | ||||||
|  | inversion contra. | ||||||
|  |  | ||||||
|  | destruct l2. | ||||||
|  | simpl. | ||||||
|  | intros contra. | ||||||
|  | inversion contra. | ||||||
|  |  | ||||||
|  | simpl. | ||||||
|  | intros eq. | ||||||
|  | inversion eq. | ||||||
|  | apply IHl1 in H0. | ||||||
|  | rewrite H0. | ||||||
|  | reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Definition sillyfun1 (n : nat) : bool := | ||||||
|  | 	 if beq_nat n (S (S (S O))) then true | ||||||
|  | 	 else if beq_nat n (S (S (S (S (S O))))) then true | ||||||
|  | 				else false. | ||||||
|  |  | ||||||
|  | Theorem beq_equal : forall (a b : nat), | ||||||
|  | 		beq_nat a b = true -> | ||||||
|  | 			a = b. | ||||||
|  | Proof. | ||||||
|  | intros a. | ||||||
|  | induction a. | ||||||
|  | destruct b. | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | intros contra. | ||||||
|  | inversion contra. | ||||||
|  |  | ||||||
|  | destruct b. | ||||||
|  | intros contra. | ||||||
|  | inversion contra. | ||||||
|  |  | ||||||
|  | simpl. | ||||||
|  | intros eq. | ||||||
|  | apply IHa in eq. | ||||||
|  | rewrite eq. | ||||||
|  | reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem override_same : forall {X : Type} x1 k1 k2 (f : nat->X), | ||||||
|  | 	f k1 = x1 -> | ||||||
|  | 		(override f k1 x1) k2 = f k2. | ||||||
|  | Proof. | ||||||
|  | 	intros X x1 k1 k2 f eq. | ||||||
|  | 	unfold override. | ||||||
|  | 	remember (beq_nat k1 k2) as a. | ||||||
|  | 	destruct a. | ||||||
|  | 	rewrite <- eq. | ||||||
|  | 	symmetry in Heqa. | ||||||
|  | 	apply beq_equal in Heqa. | ||||||
|  | 	rewrite -> Heqa. | ||||||
|  | 	reflexivity. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Theorem filter_exercise : forall (X : Type) (test : X -> bool) | ||||||
|  | 	(x : X) (l lf : list X), | ||||||
|  | 	filter _ test l = x :: lf -> | ||||||
|  | 		test x = true. | ||||||
|  | Proof. | ||||||
|  | intros X. | ||||||
|  | intros test. | ||||||
|  | intros x. | ||||||
|  | induction l. | ||||||
|  | simpl. | ||||||
|  | intros lf. | ||||||
|  | intros contra. | ||||||
|  | inversion contra. | ||||||
|  |  | ||||||
|  | simpl. | ||||||
|  | remember (test x0) as a. | ||||||
|  | destruct a. | ||||||
|  | simpl. | ||||||
|  | intros lf. | ||||||
|  | intros eq. | ||||||
|  | rewrite Heqa. | ||||||
|  | inversion eq. | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | intros lf. | ||||||
|  | intros eq. | ||||||
|  | apply IHl in eq. | ||||||
|  | rewrite eq. | ||||||
|  | reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem trans_eq : forall {X:Type} (n m o : X), | ||||||
|  | 				n = m -> m = o -> n = o. | ||||||
|  | Proof. | ||||||
|  | 	intros X n m o eq1 eq2. rewrite -> eq1. rewrite -> eq2. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Example trans_eq_example' : forall (a b c d e f : nat), | ||||||
|  | 				[a,b] = [c,d] -> | ||||||
|  | 				[c,d] = [e,f] -> | ||||||
|  | 				[a,b] = [e,f]. | ||||||
|  | Proof. | ||||||
|  | 	intros a b c d e f eq1 eq2. | ||||||
|  | 	apply trans_eq with (m := [c,d]). apply eq1. apply eq2. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Theorem trans_eq_exercise : forall (n m o p : nat), | ||||||
|  | 		m = (minustwo o) -> | ||||||
|  | 		(n + p) = m -> | ||||||
|  | 		(n + p) = (minustwo o). | ||||||
|  | Proof. | ||||||
|  | intros n m o p. | ||||||
|  | intros eq1 eq2. | ||||||
|  | rewrite eq2. | ||||||
|  | rewrite <- eq1. | ||||||
|  | reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem beq_nat_trans : forall n m p, | ||||||
|  | 				true = beq_nat n m -> | ||||||
|  | 				true = beq_nat m p -> | ||||||
|  | 				true = beq_nat n p. | ||||||
|  | Proof. | ||||||
|  | intros n m p. | ||||||
|  | intros eq1 eq2. | ||||||
|  | symmetry  in eq1. | ||||||
|  | symmetry  in eq2. | ||||||
|  | apply beq_equal in eq1. | ||||||
|  | apply beq_equal in eq2. | ||||||
|  | rewrite eq1. | ||||||
|  | rewrite <- eq2. | ||||||
|  | apply beq_nat_refl. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem override_permute : forall {X:Type} x1 x2 k1 k2 k3 (f : nat->X), | ||||||
|  | 	false = beq_nat k2 k1 -> | ||||||
|  | 	(override (override f k2 x2) k1 x1) k3 = (override (override f k1 x1) k2 x2) k3. | ||||||
|  | Proof. | ||||||
|  | intros X x1 x2 k1 k2 k3 f. | ||||||
|  | simpl. | ||||||
|  | unfold override. | ||||||
|  | remember (beq_nat k1 k3). | ||||||
|  | remember (beq_nat k2 k3). | ||||||
|  | destruct b. | ||||||
|  | destruct b0. | ||||||
|  | symmetry  in Heqb. | ||||||
|  | symmetry  in Heqb0. | ||||||
|  | apply beq_equal in Heqb. | ||||||
|  | apply beq_equal in Heqb0. | ||||||
|  | rewrite <- Heqb in Heqb0. | ||||||
|  | assert (k2 = k1 -> true = beq_nat k2 k1). | ||||||
|  | destruct k2. | ||||||
|  | destruct k1. | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | intros contra. | ||||||
|  | inversion contra. | ||||||
|  |  | ||||||
|  | destruct k1. | ||||||
|  | intros contra. | ||||||
|  | inversion contra. | ||||||
|  |  | ||||||
|  | simpl. | ||||||
|  | intros eq. | ||||||
|  | inversion eq. | ||||||
|  | symmetry . | ||||||
|  | symmetry . | ||||||
|  | apply beq_nat_refl. | ||||||
|  |  | ||||||
|  | apply H in Heqb0. | ||||||
|  | rewrite <- Heqb0. | ||||||
|  | intros contra. | ||||||
|  | inversion contra. | ||||||
|  |  | ||||||
|  | intros eq. | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | destruct b0. | ||||||
|  | intros eq. | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | intros eq. | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Definition fold_length {X : Type} (l : list X) : nat := | ||||||
|  | 	fold (fun _ n => S n) l O. | ||||||
|  |  | ||||||
|  | Example test_fold_length1 : fold_length [S (S (S (S O))), S (S (S (S (S (S (S O)))))), O] = S (S (S O)). | ||||||
|  | Proof. reflexivity. Qed. | ||||||
|  |  | ||||||
|  | Theorem fold_length_correct : forall X (l :list X), | ||||||
|  | 	fold_length l = length l. | ||||||
|  | Proof. | ||||||
|  | 	intros X l. | ||||||
|  | 	unfold fold_length. | ||||||
|  | 	induction l. | ||||||
|  | 	Case "l = O". | ||||||
|  | 		reflexivity. | ||||||
|  | 	Case "l = ::". | ||||||
|  | 		simpl. | ||||||
|  | 		rewrite IHl. | ||||||
|  | 		reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Definition fold_map {X Y: Type} (f : X -> Y) (l : list X) : list Y := | ||||||
|  | 	fold (fun x total => (f x) :: total) l []. | ||||||
|  |  | ||||||
|  | Theorem fold_map_correct : forall (X Y: Type) (f : X -> Y) (l : list X), | ||||||
|  | 	fold_map f l = map f l. | ||||||
|  | Proof. | ||||||
|  | 	intros X Y f l. | ||||||
|  | 	unfold fold_map. | ||||||
|  | 	induction l. | ||||||
|  | 	reflexivity. | ||||||
|  | 	   | ||||||
|  | 	simpl. | ||||||
|  | 	rewrite IHl. | ||||||
|  | 	reflexivity. | ||||||
|  | 	Qed. | ||||||
|  |  | ||||||
|  | Fixpoint forallb {X : Type} (f : X -> bool) (l : list X) := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => true | ||||||
|  | 		| x :: xs => andb (f x) (forallb f xs) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Fixpoint existsb {X : Type} (f : X -> bool) (l : list X) := | ||||||
|  | 	match l with | ||||||
|  | 		| nil => false | ||||||
|  | 		| x :: xs => orb (f x) (existsb f xs) | ||||||
|  | 	end. | ||||||
|  |  | ||||||
|  | Definition existsb2 {X : Type} (f: X -> bool) (l : list X) := | ||||||
|  | 	negb (forallb (fun x => negb (f x)) l). | ||||||
|  |  | ||||||
|  | Theorem existsb_correct : forall (X : Type) (f : X -> bool) (l : list X), | ||||||
|  | 		existsb f l = existsb2 f l. | ||||||
|  | Proof. | ||||||
|  | intros X f l. | ||||||
|  | induction l. | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | simpl. | ||||||
|  | rewrite IHl. | ||||||
|  | unfold existsb2. | ||||||
|  | simpl. | ||||||
|  | destruct (forallb (fun x0 : X => negb (f x0)) l). | ||||||
|  | simpl. | ||||||
|  | destruct (f x). | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | destruct (f x). | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem index_okx : forall (X:Type) (l : list X) (n : nat), | ||||||
|  | 		length l = n -> index X (S n) l = None. | ||||||
|  | Proof. | ||||||
|  | 	intros X l. | ||||||
|  | 	induction l. | ||||||
|  | 	reflexivity. | ||||||
|  |  | ||||||
|  | 	intros n. | ||||||
|  | 	destruct n. | ||||||
|  | 	intros contra. | ||||||
|  | 	inversion contra. | ||||||
|  |  | ||||||
|  | 	intros eq. | ||||||
|  | 	inversion eq. | ||||||
|  | 	apply IHl. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Inductive mumble : Type := | ||||||
|  |   | a : mumble | ||||||
|  | 	| b : mumble -> nat -> mumble | ||||||
|  | 	| c : mumble. | ||||||
|  | Inductive grumble (X:Type) : Type := | ||||||
|  |  | d : mumble -> grumble X | ||||||
|  |  | e : X -> grumble X. | ||||||
|  |  | ||||||
							
								
								
									
										312
									
								
								samples/coq/Rel.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										312
									
								
								samples/coq/Rel.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,312 @@ | |||||||
|  | Require Export Logic. | ||||||
|  | Import Playground1. | ||||||
|  |  | ||||||
|  | Definition relation (X:Type) := X -> X -> Prop. | ||||||
|  |  | ||||||
|  | Definition partial_function {X:Type} (R: relation X) := | ||||||
|  | 	forall x y1 y2 : X, R x y1 -> R x y2 -> y1 = y2. | ||||||
|  |  | ||||||
|  | Theorem next_nat_partial_function : | ||||||
|  | 	partial_function next_nat. | ||||||
|  | Proof. | ||||||
|  | 	unfold partial_function. | ||||||
|  | 	intros x y1 y2 P Q. | ||||||
|  | 	inversion P. | ||||||
|  | 	inversion Q. | ||||||
|  | 	reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem le_not_a_partial_function : | ||||||
|  | 	~ (partial_function le). | ||||||
|  | Proof. | ||||||
|  | 	unfold not. | ||||||
|  | 	unfold partial_function. | ||||||
|  | 	intros H. | ||||||
|  | 	assert (O = S O) as Nonsense. | ||||||
|  | 		Case "Proof of assertion.". | ||||||
|  | 		apply H with O. | ||||||
|  | 		apply le_n. | ||||||
|  |  | ||||||
|  | 		apply le_S. | ||||||
|  | 		apply le_n. | ||||||
|  |  | ||||||
|  | 	inversion Nonsense. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem total_relation_not_partial_function : | ||||||
|  | 	~ (partial_function total_relation). | ||||||
|  | Proof. | ||||||
|  | 	unfold not. | ||||||
|  | 	unfold partial_function. | ||||||
|  | 	intros H. | ||||||
|  | 	assert (O = S O) as Nonsense. | ||||||
|  | 	apply H with O. | ||||||
|  | 	apply total_relation1. | ||||||
|  |  | ||||||
|  | 	apply total_relation1. | ||||||
|  |  | ||||||
|  | 	inversion Nonsense. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem empty_relation_not_partial_funcion : | ||||||
|  | 	partial_function empty_relation. | ||||||
|  | Proof. | ||||||
|  | 	unfold partial_function. | ||||||
|  | 	intros x y1 y2. | ||||||
|  | 	intros H. | ||||||
|  | 	inversion H. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Definition reflexive {X:Type} (R: relation X) := | ||||||
|  | 	forall a : X, R a a. | ||||||
|  |  | ||||||
|  | Theorem le_reflexive : | ||||||
|  | 	reflexive le. | ||||||
|  | Proof. | ||||||
|  | 	unfold reflexive. | ||||||
|  | 	intros n. apply le_n. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Definition transitive {X:Type} (R: relation X) := | ||||||
|  | 	forall a b c : X, (R a b) -> (R b c) -> (R a c). | ||||||
|  |  | ||||||
|  | Theorem le_trans: | ||||||
|  | 	transitive le. | ||||||
|  | Proof. | ||||||
|  | 	intros n m o Hnm Hmo. | ||||||
|  | 	induction Hmo. | ||||||
|  | 	Case "le_n". apply Hnm. | ||||||
|  | 	Case "le_S". apply le_S. apply IHHmo. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem lt_trans: | ||||||
|  | 	transitive lt. | ||||||
|  | Proof. | ||||||
|  | 	unfold lt. unfold transitive. | ||||||
|  | 	intros n m o Hnm Hmo. | ||||||
|  | 	apply le_S in Hnm. | ||||||
|  | 	apply le_trans with (a := (S n)) (b := (S m)) (c := o). | ||||||
|  | 	apply Hnm. | ||||||
|  | 	apply Hmo. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem lt_trans' : | ||||||
|  | 	transitive lt. | ||||||
|  | Proof. | ||||||
|  | 	unfold lt. unfold transitive. | ||||||
|  | 	intros n m o Hnm Hmo. | ||||||
|  | 	induction Hmo as [| m' Hm'o]. | ||||||
|  | 	apply le_S. | ||||||
|  | 	apply Hnm. | ||||||
|  |  | ||||||
|  | 	apply le_S. | ||||||
|  | 	apply IHHm'o. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem le_Sn_le: forall n m, S n <= m -> n <= m. | ||||||
|  | Proof. | ||||||
|  | 	intros n m H. apply le_trans with (S n). | ||||||
|  | 	apply le_S. apply le_n. | ||||||
|  | 	apply H. Qed. | ||||||
|  |  | ||||||
|  | Theorem le_S_n : forall n m, | ||||||
|  | 	(S n <= S m) -> (n <= m). | ||||||
|  | Proof. | ||||||
|  | intros n m H. | ||||||
|  | apply Sn_le_Sm__n_le_m. | ||||||
|  | apply H. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem le_Sn_n : forall n, | ||||||
|  | 	~ (S n <= n). | ||||||
|  | Proof. | ||||||
|  | induction n. | ||||||
|  | intros H. | ||||||
|  | inversion H. | ||||||
|  |  | ||||||
|  | unfold not in IHn. | ||||||
|  | intros H. | ||||||
|  | apply le_S_n in H. | ||||||
|  | apply IHn. | ||||||
|  | apply H. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (* | ||||||
|  |  TODO | ||||||
|  | Theorem lt_trans'' : | ||||||
|  | 	transitive lt. | ||||||
|  | Proof. | ||||||
|  | 	unfold lt. unfold transitive. | ||||||
|  | 	intros n m o Hnm Hmo. | ||||||
|  | 	induction o as [| o']. | ||||||
|  | 	*) | ||||||
|  |  | ||||||
|  | Definition symmetric {X: Type} (R: relation X) := | ||||||
|  | 	forall a b : X, (R a b) -> (R b a). | ||||||
|  |  | ||||||
|  | Definition antisymmetric {X : Type} (R: relation X) := | ||||||
|  | 	forall a b : X, (R a b) -> (R b a) -> a = b. | ||||||
|  |  | ||||||
|  | Theorem le_antisymmetric : | ||||||
|  | 	antisymmetric le. | ||||||
|  | Proof. | ||||||
|  | intros a b. | ||||||
|  | generalize dependent a. | ||||||
|  | induction b. | ||||||
|  | intros a. | ||||||
|  | intros H. | ||||||
|  | intros H1. | ||||||
|  | inversion H. | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | intros a H1 H2. | ||||||
|  | destruct a. | ||||||
|  | inversion H2. | ||||||
|  |  | ||||||
|  | apply Sn_le_Sm__n_le_m in H1. | ||||||
|  | apply Sn_le_Sm__n_le_m in H2. | ||||||
|  | apply IHb in H1. | ||||||
|  | rewrite H1 in |- *. | ||||||
|  | reflexivity. | ||||||
|  |  | ||||||
|  | apply H2. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (* | ||||||
|  |  TODO | ||||||
|  | Theorem le_step : forall n m p, | ||||||
|  | 	n < m -> | ||||||
|  | 	n <= S p -> | ||||||
|  | 	n <= p. | ||||||
|  | Proof. | ||||||
|  | *) | ||||||
|  |  | ||||||
|  | Definition equivalence {X:Type} (R: relation X) := | ||||||
|  | 	(reflexive R) /\ (symmetric R) /\ (transitive R). | ||||||
|  |  | ||||||
|  | Definition order {X:Type} (R: relation X) := | ||||||
|  | 	(reflexive R) /\ (antisymmetric R) /\ (transitive R). | ||||||
|  |  | ||||||
|  | Definition preorder {X:Type} (R: relation X) := | ||||||
|  | 	(reflexive R) /\ (transitive R). | ||||||
|  |  | ||||||
|  | Theorem le_order : | ||||||
|  | 	order le. | ||||||
|  | Proof. | ||||||
|  | 	unfold order. split. | ||||||
|  | 	Case "refl". apply le_reflexive. | ||||||
|  | 	split. | ||||||
|  | 		Case "antisym". apply le_antisymmetric. | ||||||
|  | 		Case "transitive". apply le_trans. Qed. | ||||||
|  |  | ||||||
|  | Inductive clos_refl_trans {A:Type} (R: relation A) : relation A := | ||||||
|  | 	| rt_step : forall x y, R x y -> clos_refl_trans R x y | ||||||
|  | 	| rt_refl : forall x, clos_refl_trans R x x | ||||||
|  | 	| rt_trans : forall x y z, | ||||||
|  | 		clos_refl_trans R x y -> clos_refl_trans R y z -> clos_refl_trans R x z. | ||||||
|  |  | ||||||
|  | Theorem next_nat_closure_is_le : forall n m, | ||||||
|  | 	(n <= m) <-> ((clos_refl_trans next_nat) n m). | ||||||
|  | Proof. | ||||||
|  | intros n m. | ||||||
|  | split. | ||||||
|  | intro H. | ||||||
|  | induction H. | ||||||
|  | apply rt_refl. | ||||||
|  |  | ||||||
|  | apply rt_trans with m. | ||||||
|  | apply IHle. | ||||||
|  |  | ||||||
|  | apply rt_step. | ||||||
|  | apply nn. | ||||||
|  |  | ||||||
|  | intro H. | ||||||
|  | induction H. | ||||||
|  | inversion H. | ||||||
|  | apply le_S. | ||||||
|  | apply le_n. | ||||||
|  |  | ||||||
|  | apply le_n. | ||||||
|  |  | ||||||
|  | apply le_trans with y. | ||||||
|  | apply IHclos_refl_trans1. | ||||||
|  |  | ||||||
|  | apply IHclos_refl_trans2. | ||||||
|  | Qed.																     | ||||||
|  |  | ||||||
|  | Inductive refl_step_closure {X : Type} (R: relation X) | ||||||
|  | 											: X -> X -> Prop := | ||||||
|  | 	| rsc_refl : forall (x : X), refl_step_closure R x x | ||||||
|  | 	| rsc_step : forall (x y z : X), R x y -> | ||||||
|  | 								refl_step_closure R y z -> | ||||||
|  | 								refl_step_closure R x z. | ||||||
|  |  | ||||||
|  | Tactic Notation "rt_cases" tactic(first) ident(c) := | ||||||
|  | 	first; | ||||||
|  | 	[ Case_aux c "rt_step" | Case_aux c "rt_refl" | Case_aux c "rt_trans" ]. | ||||||
|  |  | ||||||
|  | Tactic Notation "rsc_cases" tactic(first) ident(c) := | ||||||
|  | 	  first; | ||||||
|  | 		  [ Case_aux c "rsc_refl" | Case_aux c "rsc_step" ]. | ||||||
|  |  | ||||||
|  | Theorem rsc_R : forall (X:Type) (R:relation X) (x y:X), | ||||||
|  | 				R x y -> refl_step_closure R x y. | ||||||
|  | Proof. | ||||||
|  | intros X R x y r. | ||||||
|  | apply rsc_step with y. | ||||||
|  |  apply r. | ||||||
|  |    | ||||||
|  |   apply rsc_refl. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem rsc_trans : | ||||||
|  | 	forall (X : Type) (R : relation X) (x y z : X), | ||||||
|  | 		refl_step_closure R x y -> | ||||||
|  | 			refl_step_closure R y z -> | ||||||
|  | 				refl_step_closure R x z. | ||||||
|  | Proof. | ||||||
|  | intros X. | ||||||
|  | intros R x y z. | ||||||
|  | intros H. | ||||||
|  | induction H. | ||||||
|  | intros H1. | ||||||
|  | apply H1. | ||||||
|  |  | ||||||
|  | intros H1. | ||||||
|  | apply IHrefl_step_closure in H1. | ||||||
|  | apply rsc_step with y. | ||||||
|  | apply H. | ||||||
|  |  | ||||||
|  | apply H1. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem rtc_rsc_coincide: | ||||||
|  | 	forall (X:Type) (R: relation X) (x y : X), | ||||||
|  | 		clos_refl_trans R x y <-> refl_step_closure R x y. | ||||||
|  | Proof. | ||||||
|  | intros X R x y. | ||||||
|  | split. | ||||||
|  | intros H. | ||||||
|  | induction H. | ||||||
|  | apply rsc_step with y. | ||||||
|  | apply H. | ||||||
|  |  | ||||||
|  | apply rsc_refl. | ||||||
|  |  | ||||||
|  | apply rsc_refl. | ||||||
|  |  | ||||||
|  | apply rsc_trans with y. | ||||||
|  | apply IHclos_refl_trans1. | ||||||
|  |  | ||||||
|  | apply IHclos_refl_trans2. | ||||||
|  |  | ||||||
|  | intros H1. | ||||||
|  | induction H1. | ||||||
|  | apply rt_refl. | ||||||
|  |  | ||||||
|  | apply rt_trans with y. | ||||||
|  | apply rt_step. | ||||||
|  | apply H. | ||||||
|  |  | ||||||
|  | apply IHrefl_step_closure. | ||||||
|  | Qed. | ||||||
							
								
								
									
										701
									
								
								samples/coq/Smallstep.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										701
									
								
								samples/coq/Smallstep.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,701 @@ | |||||||
|  | Require Export Imp. | ||||||
|  | Require Export Relations. | ||||||
|  |  | ||||||
|  | Inductive tm : Type := | ||||||
|  |    | tm_const : nat -> tm | ||||||
|  |    | tm_plus : tm -> tm -> tm. | ||||||
|  |  | ||||||
|  | Tactic Notation "tm_cases" tactic(first) ident(c) := | ||||||
|  |    first; | ||||||
|  |    [ Case_aux c "tm_const" | Case_aux c "tm_plus" ]. | ||||||
|  |  | ||||||
|  | Module SimpleArith0. | ||||||
|  |  | ||||||
|  | Fixpoint eval (t : tm) : nat := | ||||||
|  |    match t with | ||||||
|  |       | tm_const n => n | ||||||
|  |       | tm_plus a1 a2 => eval a1 + eval a2 | ||||||
|  |    end. | ||||||
|  |  | ||||||
|  | End SimpleArith0. | ||||||
|  |  | ||||||
|  | Module SimpleArith1. | ||||||
|  |  | ||||||
|  | Reserved Notation " t '===>' n " (at level 50, left associativity). | ||||||
|  |  | ||||||
|  | Inductive eval : tm -> nat -> Prop := | ||||||
|  |    | E_Const : forall n, | ||||||
|  |                   tm_const n ===> n | ||||||
|  |    | E_Plus : forall t1 t2 n1 n2, | ||||||
|  |                   t1 ===> n1 -> | ||||||
|  |                   t2 ===> n2 -> | ||||||
|  |                   tm_plus t1 t2 ===> plus n1 n2 | ||||||
|  |  | ||||||
|  |      where " t '===>' n " := (eval t n). | ||||||
|  |  | ||||||
|  | End SimpleArith1. | ||||||
|  |  | ||||||
|  | Reserved Notation " t '===>' t' " (at level 50, left associativity). | ||||||
|  |  | ||||||
|  | Inductive eval : tm -> tm -> Prop := | ||||||
|  |    | E_Const : forall n1, | ||||||
|  |       tm_const n1 ===> tm_const n1 | ||||||
|  |    | E_Plus : forall t1 n1 t2 n2, | ||||||
|  |       t1 ===> tm_const n1 -> | ||||||
|  |       t2 ===> tm_const n2 -> | ||||||
|  |          tm_plus t1 t2 ===> tm_const (plus n1 n2) | ||||||
|  |    where " t '===>' t' " := (eval t t'). | ||||||
|  |  | ||||||
|  | Tactic Notation "eval_cases" tactic(first) ident(c) := | ||||||
|  |    first; | ||||||
|  |    [ Case_aux c "E_Const" | Case_aux c "E_Plus" ]. | ||||||
|  |  | ||||||
|  | Module SimpleArith2. | ||||||
|  |  | ||||||
|  | Reserved Notation " t '=>' t' " (at level 40). | ||||||
|  |  | ||||||
|  | Inductive step : tm -> tm -> Prop := | ||||||
|  |    | ST_PlusConstConst : forall n1 n2, | ||||||
|  |       tm_plus (tm_const n1) (tm_const n2) => tm_const (plus n1 n2) | ||||||
|  |    | ST_Plus1 : forall t1 t1' t2, | ||||||
|  |       t1 => t1' -> | ||||||
|  |          tm_plus t1 t2 => tm_plus t1' t2 | ||||||
|  |    | ST_Plus2 : forall n1 t2 t2', | ||||||
|  |       t2 => t2' -> | ||||||
|  |       tm_plus (tm_const n1) t2 => tm_plus (tm_const n1) t2' | ||||||
|  |  | ||||||
|  |    where " t '=>' t' " := (step t t'). | ||||||
|  |  | ||||||
|  | Tactic Notation "step_cases" tactic(first) ident(c) := | ||||||
|  |    first; | ||||||
|  |    [ Case_aux c "ST_PlusConstConst" | ||||||
|  |    | Case_aux c "ST_Plus1" | Case_aux c "ST_Plus2" ]. | ||||||
|  |  | ||||||
|  | Example test_step_1 :  | ||||||
|  |       tm_plus  | ||||||
|  |         (tm_plus (tm_const 0) (tm_const 3)) | ||||||
|  |         (tm_plus (tm_const 2) (tm_const 4)) | ||||||
|  |       => | ||||||
|  |       tm_plus  | ||||||
|  |         (tm_const (plus 0 3)) | ||||||
|  |         (tm_plus (tm_const 2) (tm_const 4)). | ||||||
|  | Proof. | ||||||
|  |   apply ST_Plus1. apply ST_PlusConstConst. Qed. | ||||||
|  |  | ||||||
|  | Example test_step_2 :  | ||||||
|  |       tm_plus  | ||||||
|  |         (tm_const 0) | ||||||
|  |         (tm_plus  | ||||||
|  |           (tm_const 2)  | ||||||
|  |           (tm_plus (tm_const 0) (tm_const 3))) | ||||||
|  |       => | ||||||
|  |       tm_plus  | ||||||
|  |         (tm_const 0) | ||||||
|  |         (tm_plus  | ||||||
|  |           (tm_const 2)  | ||||||
|  |           (tm_const (plus 0 3))). | ||||||
|  | Proof. | ||||||
|  | apply ST_Plus2. | ||||||
|  | simpl. | ||||||
|  | apply ST_Plus2. | ||||||
|  | apply ST_PlusConstConst. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem step_deterministic: | ||||||
|  |   partial_function step. | ||||||
|  | Proof. | ||||||
|  |   unfold partial_function. intros x y1 y2 Hy1 Hy2. | ||||||
|  |   generalize dependent y2. | ||||||
|  |   step_cases (induction Hy1) Case; intros y2 Hy2. | ||||||
|  |     Case "ST_PlusConstConst". step_cases (inversion Hy2) SCase. | ||||||
|  |       SCase "ST_PlusConstConst". reflexivity. | ||||||
|  |       SCase "ST_Plus1". inversion H2. | ||||||
|  |       SCase "ST_Plus2". inversion H2. | ||||||
|  |     Case "ST_Plus1". step_cases (inversion Hy2) SCase. | ||||||
|  |       SCase "ST_PlusConstConst". rewrite <- H0 in Hy1. inversion Hy1. | ||||||
|  |       SCase "ST_Plus1". | ||||||
|  |         rewrite <- (IHHy1 t1'0). | ||||||
|  |         reflexivity. assumption. | ||||||
|  |       SCase "ST_Plus2". rewrite <- H in Hy1. inversion Hy1. | ||||||
|  |     Case "ST_Plus2". step_cases (inversion Hy2) SCase. | ||||||
|  |       SCase "ST_PlusConstConst". rewrite <- H1 in Hy1. inversion Hy1. | ||||||
|  |       SCase "ST_Plus1". inversion H2. | ||||||
|  |       SCase "ST_Plus2". | ||||||
|  |         rewrite <- (IHHy1 t2'0). | ||||||
|  |         reflexivity. assumption. Qed. | ||||||
|  |  | ||||||
|  | End SimpleArith2. | ||||||
|  |  | ||||||
|  | Inductive value : tm -> Prop := | ||||||
|  |    v_const: forall n, value (tm_const n). | ||||||
|  |  | ||||||
|  | Reserved Notation " t '=>' t' " (at level 40). | ||||||
|  |  | ||||||
|  | Inductive step : tm -> tm -> Prop := | ||||||
|  |    | ST_PlusConstConst : forall n1 n2, | ||||||
|  |       tm_plus (tm_const n1) (tm_const n2) | ||||||
|  |          => tm_const (plus n1 n2) | ||||||
|  |    | ST_Plus1 : forall t1 t1' t2, | ||||||
|  |       t1 => t1' -> | ||||||
|  |          tm_plus t1 t2 => tm_plus t1' t2 | ||||||
|  |    | ST_Plus2 : forall v1 t2 t2', | ||||||
|  |       value v1 -> | ||||||
|  |          t2 => t2' -> | ||||||
|  |             tm_plus v1 t2 => tm_plus v1 t2' | ||||||
|  |  | ||||||
|  |    where " t '=>' t' " := (step t t'). | ||||||
|  |  | ||||||
|  | Tactic Notation "step_cases" tactic(first) ident(c) := | ||||||
|  |    first; | ||||||
|  |    [ Case_aux c "ST_PlusConstConst" | ||||||
|  |       | Case_aux c "ST_Plus1" | Case_aux c "ST_Plus2" ]. | ||||||
|  |  | ||||||
|  | Theorem step_deterministic : | ||||||
|  |    partial_function step. | ||||||
|  | Proof. | ||||||
|  | unfold partial_function. | ||||||
|  | intros x y1 y2 Hy1 Hy2. | ||||||
|  | generalize dependent y2. | ||||||
|  | step_cases (induction Hy1) Case; intros y2 Hy2. | ||||||
|  |  step_cases (inversion Hy2) SCase. | ||||||
|  |   reflexivity. | ||||||
|  |    | ||||||
|  |   inversion H2. | ||||||
|  |    | ||||||
|  |   inversion Hy2. | ||||||
|  |    subst. | ||||||
|  |    assumption. | ||||||
|  |     | ||||||
|  |    subst. | ||||||
|  |    inversion H3. | ||||||
|  |     | ||||||
|  |    subst. | ||||||
|  |    inversion H3. | ||||||
|  |     | ||||||
|  |  step_cases (inversion Hy2) SCase. | ||||||
|  |   rewrite <- H0 in Hy1. | ||||||
|  |   inversion Hy1. | ||||||
|  |    | ||||||
|  |   rewrite <- (IHHy1 t1'0). | ||||||
|  |    reflexivity. | ||||||
|  |     | ||||||
|  |    assumption. | ||||||
|  |     | ||||||
|  |   rewrite <- H in Hy1. | ||||||
|  |   rewrite <- H in H1. | ||||||
|  |   subst. | ||||||
|  |   inversion H1. | ||||||
|  |   subst. | ||||||
|  |   inversion Hy1. | ||||||
|  |    | ||||||
|  |  step_cases (inversion Hy2) SCase. | ||||||
|  |   subst. | ||||||
|  |   inversion Hy1. | ||||||
|  |    | ||||||
|  |   subst. | ||||||
|  |   inversion H. | ||||||
|  |   subst. | ||||||
|  |   inversion H3. | ||||||
|  |    | ||||||
|  |   subst. | ||||||
|  |   inversion H2. | ||||||
|  |   subst. | ||||||
|  |   rewrite <- (IHHy1 t2'0). | ||||||
|  |    reflexivity. | ||||||
|  |     | ||||||
|  |    assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem strong_progress : forall t, | ||||||
|  |         value t \/ (exists t', t => t'). | ||||||
|  | Proof. | ||||||
|  |    tm_cases (induction t) Case. | ||||||
|  |       Case "tm_const". left. apply v_const. | ||||||
|  |       Case "tm_plus". right. inversion IHt1. | ||||||
|  |          SCase "l". inversion IHt2. | ||||||
|  |             SSCase "l". inversion H. inversion H0. | ||||||
|  |                exists (tm_const (plus n n0)). | ||||||
|  |                apply ST_PlusConstConst. | ||||||
|  |             SSCase "r". inversion H0 as [t' H1]. | ||||||
|  |                exists (tm_plus t1 t'). | ||||||
|  |                apply ST_Plus2. apply H. apply H1. | ||||||
|  |          SCase "r". inversion H as [t' H0]. | ||||||
|  |             exists (tm_plus t' t2). | ||||||
|  |             apply ST_Plus1. apply H0. Qed. | ||||||
|  |  | ||||||
|  | Definition normal_form {X:Type} (R: relation X) (t: X) : Prop := | ||||||
|  |     ~ (exists t', R t t').  | ||||||
|  |  | ||||||
|  | Lemma value_is_nf: forall t, | ||||||
|  |       value t -> normal_form step t. | ||||||
|  | Proof. | ||||||
|  |    unfold normal_form. intros t H. inversion H. | ||||||
|  |    intros contra. inversion contra. inversion H1. | ||||||
|  |    Qed. | ||||||
|  |  | ||||||
|  | Lemma nf_is_value: forall t, | ||||||
|  |       normal_form step t -> value t. | ||||||
|  | Proof. | ||||||
|  |    unfold normal_form. intros t H. | ||||||
|  |    assert (G: value t \/ (exists t', t => t')). | ||||||
|  |       SCase "Proof of assertion". apply strong_progress. | ||||||
|  |    inversion G. | ||||||
|  |       SCase "l". assumption. | ||||||
|  |       SCase "r". apply ex_falso_quodlibet. apply H. assumption. Qed. | ||||||
|  |  | ||||||
|  | Corollary nf_same_as_value : forall t, | ||||||
|  |             normal_form step t <-> value t. | ||||||
|  | Proof. | ||||||
|  |    split. apply nf_is_value. apply value_is_nf. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Module Temp1. | ||||||
|  |  | ||||||
|  | Inductive value : tm -> Prop := | ||||||
|  | | v_const : forall n, value (tm_const n) | ||||||
|  | | v_funny : forall t1 n2, (* <---- *) | ||||||
|  |               value (tm_plus t1 (tm_const n2)). | ||||||
|  |  | ||||||
|  | Reserved Notation " t '=>' t' " (at level 40). | ||||||
|  |  | ||||||
|  | Inductive step : tm -> tm -> Prop := | ||||||
|  |   | ST_PlusConstConst : forall n1 n2, | ||||||
|  |       tm_plus (tm_const n1) (tm_const n2) => tm_const (plus n1 n2) | ||||||
|  |   | ST_Plus1 : forall t1 t1' t2, | ||||||
|  |       t1 => t1' -> | ||||||
|  |       tm_plus t1 t2 => tm_plus t1' t2 | ||||||
|  |   | ST_Plus2 : forall v1 t2 t2', | ||||||
|  |       value v1 -> | ||||||
|  |       t2 => t2' -> | ||||||
|  |       tm_plus v1 t2 => tm_plus v1 t2' | ||||||
|  |  | ||||||
|  |   where " t '=>' t' " := (step t t'). | ||||||
|  |  | ||||||
|  | Lemma value_not_same_as_normal_form: | ||||||
|  |    exists t, value t /\ ~ normal_form step t. | ||||||
|  | Proof. | ||||||
|  | intros. | ||||||
|  | unfold normal_form. | ||||||
|  | exists (tm_plus (tm_plus (tm_const 1) (tm_const 2)) (tm_const 2)). | ||||||
|  | split. | ||||||
|  |  apply v_funny. | ||||||
|  |   | ||||||
|  |  unfold not. | ||||||
|  |  intros. | ||||||
|  |  apply H. | ||||||
|  |  exists (tm_plus (tm_const (1 + 2)) (tm_const 2)). | ||||||
|  |  apply ST_Plus1. | ||||||
|  |  apply ST_PlusConstConst. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Temp1. | ||||||
|  |  | ||||||
|  | Module Temp2. | ||||||
|  |  | ||||||
|  | Inductive value : tm -> Prop := | ||||||
|  |    | v_const : forall n, value (tm_const n). | ||||||
|  |  | ||||||
|  | (*Reserved Notation " t '===>' t' " (at level 40).*) | ||||||
|  |  | ||||||
|  | Inductive step : tm -> tm -> Prop := | ||||||
|  |   | ST_Funny : forall n, (* <---- *) | ||||||
|  |       tm_const n ===> tm_plus (tm_const n) (tm_const 0) | ||||||
|  |   | ST_PlusConstConst : forall n1 n2, | ||||||
|  |       tm_plus (tm_const n1) (tm_const n2) ===> tm_const (plus n1 n2) | ||||||
|  |   | ST_Plus1 : forall t1 t1' t2, | ||||||
|  |       t1 ===> t1' -> | ||||||
|  |       tm_plus t1 t2 ===> tm_plus t1' t2 | ||||||
|  |   | ST_Plus2 : forall v1 t2 t2', | ||||||
|  |       value v1 -> | ||||||
|  |       t2 ===> t2' -> | ||||||
|  |       tm_plus v1 t2 ===> tm_plus v1 t2' | ||||||
|  |  | ||||||
|  |   where " t '===>' t' " := (step t t'). | ||||||
|  |  | ||||||
|  | Lemma value_not_same_as_normal_form : | ||||||
|  |   exists t, value t /\ ~ normal_form step t. | ||||||
|  | Proof. | ||||||
|  | exists (tm_const 0). | ||||||
|  | split. | ||||||
|  |  apply v_const. | ||||||
|  |   | ||||||
|  |  unfold normal_form. | ||||||
|  |  unfold not. | ||||||
|  |  intro H. | ||||||
|  |  apply H. | ||||||
|  |  exists (tm_plus (tm_const 0) (tm_const 0)). | ||||||
|  |  apply ST_Funny. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Temp2. | ||||||
|  |  | ||||||
|  | Module Temp3. | ||||||
|  |  | ||||||
|  | Inductive value : tm -> Prop := | ||||||
|  |   | v_const : forall n, value (tm_const n). | ||||||
|  |  | ||||||
|  | (*Reserved Notation " t '===>' t' " (at level 40).*) | ||||||
|  |  | ||||||
|  | Inductive step : tm -> tm -> Prop := | ||||||
|  |   | ST_PlusConstConst : forall n1 n2, | ||||||
|  |       tm_plus (tm_const n1) (tm_const n2) ===> tm_const (plus n1 n2) | ||||||
|  |   | ST_Plus1 : forall t1 t1' t2, | ||||||
|  |       t1 ===> t1' -> | ||||||
|  |       tm_plus t1 t2 ===> tm_plus t1' t2 | ||||||
|  |  | ||||||
|  |   where " t '===>' t' " := (step t t'). | ||||||
|  |  | ||||||
|  | Lemma value_not_same_as_normal_form: | ||||||
|  |    exists t, ~ value t /\ normal_form step t. | ||||||
|  | Proof. | ||||||
|  | exists (tm_plus (tm_const 1) (tm_plus (tm_const 0) (tm_const 0))). | ||||||
|  | split. | ||||||
|  |  intros H. | ||||||
|  |  inversion H. | ||||||
|  |   | ||||||
|  |  unfold normal_form. | ||||||
|  |  intros H. | ||||||
|  |  inversion H. | ||||||
|  |  inversion H0. | ||||||
|  |  inversion H4. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Temp3. | ||||||
|  |  | ||||||
|  | Module Temp4. | ||||||
|  | Inductive tm : Type := | ||||||
|  |    | tm_true : tm | ||||||
|  |    | tm_false : tm | ||||||
|  |    | tm_if : tm -> tm -> tm -> tm. | ||||||
|  |  | ||||||
|  | Inductive value : tm -> Prop := | ||||||
|  |    | v_true : value tm_true | ||||||
|  |    | v_false : value tm_false. | ||||||
|  |  | ||||||
|  | Inductive step : tm -> tm -> Prop := | ||||||
|  |    | ST_IfTrue : forall t1 t2, | ||||||
|  |       tm_if tm_true t1 t2 ===> t1 | ||||||
|  |    | ST_IfFalse : forall t1 t2, | ||||||
|  |       tm_if tm_false t1 t2 ===> t2 | ||||||
|  |    | ST_If : forall t1 t1' t2 t3, | ||||||
|  |       t1 ===> t1' -> | ||||||
|  |          tm_if t1 t2 t3 ===> tm_if t1' t2 t3 | ||||||
|  |  | ||||||
|  |    where " t '===>' t' " := (step t t'). | ||||||
|  |  | ||||||
|  | Example bool_step_prop3 : | ||||||
|  |      tm_if | ||||||
|  |        (tm_if tm_true tm_true tm_true) | ||||||
|  |        (tm_if tm_true tm_true tm_true) | ||||||
|  |        tm_false | ||||||
|  |    ===> | ||||||
|  |      tm_if | ||||||
|  |        tm_true | ||||||
|  |        (tm_if tm_true tm_true tm_true) | ||||||
|  |        tm_false. | ||||||
|  | Proof. | ||||||
|  | apply ST_If. | ||||||
|  | apply ST_IfTrue. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem strong_progress: forall t, | ||||||
|  |         value t \/ (exists t', t ===> t'). | ||||||
|  | Proof. | ||||||
|  | induction t. | ||||||
|  |  left. | ||||||
|  |  constructor. | ||||||
|  |   | ||||||
|  |  left. | ||||||
|  |  constructor. | ||||||
|  |   | ||||||
|  |  right. | ||||||
|  |  inversion IHt1. | ||||||
|  |   inversion H. | ||||||
|  |    exists t2. | ||||||
|  |    apply ST_IfTrue. | ||||||
|  |     | ||||||
|  |    exists t3. | ||||||
|  |    apply ST_IfFalse. | ||||||
|  |     | ||||||
|  |   inversion H. | ||||||
|  |   exists (tm_if x t2 t3). | ||||||
|  |   apply ST_If. | ||||||
|  |   assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem step_deterministic : | ||||||
|  |   partial_function step. | ||||||
|  | Proof. | ||||||
|  | unfold partial_function. | ||||||
|  | intros x y1 y2 Hy1 Hy2. | ||||||
|  | generalize dependent y2. | ||||||
|  | induction Hy1. | ||||||
|  |  intros. | ||||||
|  |  inversion Hy2. | ||||||
|  |   reflexivity. | ||||||
|  |    | ||||||
|  |   subst. | ||||||
|  |   inversion H3. | ||||||
|  |    | ||||||
|  |  intros. | ||||||
|  |  inversion Hy2. | ||||||
|  |   reflexivity. | ||||||
|  |    | ||||||
|  |   inversion H3. | ||||||
|  |    | ||||||
|  |  intros. | ||||||
|  |  inversion Hy2. | ||||||
|  |   subst. | ||||||
|  |   inversion Hy1. | ||||||
|  |    | ||||||
|  |   subst. | ||||||
|  |   inversion Hy1. | ||||||
|  |    | ||||||
|  |   subst. | ||||||
|  |   apply IHHy1 in H3. | ||||||
|  |   subst. | ||||||
|  |   reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Module Temp5. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Inductive step : tm -> tm -> Prop := | ||||||
|  |    | ST_IfTrue : forall t1 t2, | ||||||
|  |       tm_if tm_true t1 t2 ===> t1 | ||||||
|  |    | ST_IfFalse : forall t1 t2, | ||||||
|  |       tm_if tm_false t1 t2 ===> t2 | ||||||
|  |    | ST_If : forall t1 t1' t2 t3, | ||||||
|  |       t1 ===> t1' -> | ||||||
|  |          tm_if t1 t2 t3 ===> tm_if t1' t2 t3 | ||||||
|  |    | ST_ShortCut : forall v t, | ||||||
|  |       value v -> | ||||||
|  |          tm_if t v v ===> v | ||||||
|  |  | ||||||
|  |    where " t '===>' t' " := (step t t'). | ||||||
|  |  | ||||||
|  | Definition bool_step_prop4 := | ||||||
|  |          tm_if | ||||||
|  |             (tm_if tm_true tm_true tm_true) | ||||||
|  |             tm_false | ||||||
|  |             tm_false | ||||||
|  |      ===> | ||||||
|  |          tm_false. | ||||||
|  |  | ||||||
|  | Example bool_step_prop4_holds :  | ||||||
|  |   bool_step_prop4. | ||||||
|  | Proof. | ||||||
|  |    unfold bool_step_prop4. | ||||||
|  |    apply ST_ShortCut. | ||||||
|  |    constructor. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem strong_progress: forall t, | ||||||
|  |         value t \/ (exists t', t ===> t'). | ||||||
|  | Proof. | ||||||
|  |    induction t. | ||||||
|  |  left. | ||||||
|  |  constructor. | ||||||
|  |   | ||||||
|  |  left. | ||||||
|  |  constructor. | ||||||
|  |   | ||||||
|  |  inversion IHt1. | ||||||
|  |   right. | ||||||
|  |   inversion H. | ||||||
|  |    exists t2. | ||||||
|  |    constructor. | ||||||
|  |     | ||||||
|  |    exists t3. | ||||||
|  |    constructor. | ||||||
|  |     | ||||||
|  |   right. | ||||||
|  |   inversion H. | ||||||
|  |   exists (tm_if x t2 t3). | ||||||
|  |   apply ST_If. | ||||||
|  |   assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Temp5. | ||||||
|  | End Temp4. | ||||||
|  |  | ||||||
|  | Definition stepmany := refl_step_closure step. | ||||||
|  |  | ||||||
|  | Notation " t '===>*' t' " := (stepmany t t') (at level 40). | ||||||
|  |  | ||||||
|  | Lemma test_stepmany_1: | ||||||
|  |    tm_plus | ||||||
|  |       (tm_plus (tm_const 0) (tm_const 3)) | ||||||
|  |       (tm_plus (tm_const 2) (tm_const 4)) | ||||||
|  |       ===>* | ||||||
|  |          tm_const (plus (plus 0 3) (plus 2 4)). | ||||||
|  | Proof. | ||||||
|  |    eapply rsc_step. apply ST_Plus1. apply ST_PlusConstConst. | ||||||
|  |   eapply rsc_step. apply ST_Plus2. apply v_const. | ||||||
|  |   apply ST_PlusConstConst. | ||||||
|  |   eapply rsc_step. apply ST_PlusConstConst. | ||||||
|  |   apply rsc_refl. Qed. | ||||||
|  |  | ||||||
|  | Lemma test_stepmany_2: | ||||||
|  |    tm_const 3 ===>* tm_const 3. | ||||||
|  | Proof. | ||||||
|  |    eapply rsc_refl. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma test_stepmany_3: | ||||||
|  |    tm_plus (tm_const 0) (tm_const 3) | ||||||
|  |       ===>* | ||||||
|  |    tm_plus (tm_const 0) (tm_const 3). | ||||||
|  | Proof. | ||||||
|  |    eapply rsc_refl. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma test_stepmany_4: | ||||||
|  |    tm_plus | ||||||
|  |       (tm_const 0) | ||||||
|  |       (tm_plus | ||||||
|  |          (tm_const 2) | ||||||
|  |          (tm_plus (tm_const 0) (tm_const 3))) | ||||||
|  |    ===>* | ||||||
|  |       tm_plus | ||||||
|  |          (tm_const 0) | ||||||
|  |          (tm_const (plus 2 (plus 0 3))). | ||||||
|  | Proof. | ||||||
|  | eapply rsc_step. | ||||||
|  |  apply ST_Plus2. | ||||||
|  |   apply v_const. | ||||||
|  |    | ||||||
|  |   apply ST_Plus2. | ||||||
|  |    apply v_const. | ||||||
|  |     | ||||||
|  |    apply ST_PlusConstConst. | ||||||
|  |     | ||||||
|  |  eapply rsc_step. | ||||||
|  |   apply ST_Plus2. | ||||||
|  |    apply v_const. | ||||||
|  |     | ||||||
|  |    apply ST_PlusConstConst. | ||||||
|  |     | ||||||
|  |   eapply rsc_refl. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Definition step_normal_form := normal_form step. | ||||||
|  |  | ||||||
|  | Definition normal_form_of (t t' : tm) := | ||||||
|  |   (t ===>* t' /\ step_normal_form t'). | ||||||
|  |  | ||||||
|  |    (* | ||||||
|  | Theorem normal_forms_unique: | ||||||
|  |    partial_function normal_form_of. | ||||||
|  | Proof. | ||||||
|  |    unfold partial_function. unfold normal_form_of. intros x y1 y2 P1 P2. | ||||||
|  |    destruct P1 as [P11 P12]. destruct P2 as [P21 P22]. | ||||||
|  |    generalize dependent y2. | ||||||
|  |  | ||||||
|  |    unfold step_normal_form in P12. | ||||||
|  |    unfold step_normal_form. | ||||||
|  |    unfold normal_form. | ||||||
|  |    unfold normal_form in P12. | ||||||
|  |    induction x. | ||||||
|  |    intros. | ||||||
|  |    unfold stepmany. | ||||||
|  |    inversion P11. | ||||||
|  |    subst. | ||||||
|  |    inversion P21. | ||||||
|  |    subst. | ||||||
|  |    reflexivity. | ||||||
|  |  | ||||||
|  |    subst. | ||||||
|  |    inversion P21. | ||||||
|  |    reflexivity. | ||||||
|  |  | ||||||
|  |    subst. | ||||||
|  |    inversion H1. | ||||||
|  |  | ||||||
|  |    inversion H. | ||||||
|  |    *) | ||||||
|  |  | ||||||
|  | Definition normalizing {X:Type} (R:relation X) := | ||||||
|  |      forall t, exists t', | ||||||
|  |          (refl_step_closure R) t t' /\ normal_form R t'. | ||||||
|  |  | ||||||
|  | Lemma stepmany_congr_1 : forall t1 t1' t2, | ||||||
|  |       t1 ===>* t1' -> | ||||||
|  |          tm_plus t1 t2 ===>* tm_plus t1' t2. | ||||||
|  | Proof. | ||||||
|  | intros t1 t1' t2 H. | ||||||
|  | rsc_cases (induction H) Case. | ||||||
|  |  apply rsc_refl. | ||||||
|  |    | ||||||
|  |   apply rsc_step with (tm_plus y t2). | ||||||
|  |     apply ST_Plus1. | ||||||
|  |       apply H. | ||||||
|  |          | ||||||
|  |         apply IHrefl_step_closure. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma stepmany_congr2 : forall t1 t2 t2', | ||||||
|  |       value t1 -> | ||||||
|  |          t2 ===>* t2' -> | ||||||
|  |             tm_plus t1 t2 ===>* tm_plus t1 t2'. | ||||||
|  | Proof. | ||||||
|  | intros t1 t2 t2'. | ||||||
|  | intros H1. | ||||||
|  | intros H2. | ||||||
|  | induction H2. | ||||||
|  |  apply rsc_refl. | ||||||
|  |    | ||||||
|  |   apply rsc_step with (tm_plus t1 y). | ||||||
|  |     apply ST_Plus2. | ||||||
|  |        assumption. | ||||||
|  |            | ||||||
|  |           assumption. | ||||||
|  |               | ||||||
|  |             assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem step_normalizing : | ||||||
|  |   normalizing step. | ||||||
|  | Proof. | ||||||
|  |   unfold normalizing. | ||||||
|  |   tm_cases (induction t) Case. | ||||||
|  |     Case "tm_const". | ||||||
|  |       exists (tm_const n). | ||||||
|  |       split. | ||||||
|  |       SCase "l". apply rsc_refl. | ||||||
|  |       SCase "r". | ||||||
|  |         (* We can use rewrite with "iff" statements, not | ||||||
|  |            just equalities: *) | ||||||
|  |         rewrite nf_same_as_value. apply v_const. | ||||||
|  |     Case "tm_plus". | ||||||
|  |       destruct IHt1 as [t1' H1]. destruct IHt2 as [t2' H2]. | ||||||
|  |       destruct H1 as [H11 H12]. destruct H2 as [H21 H22]. | ||||||
|  |       rewrite nf_same_as_value in H12. rewrite nf_same_as_value in H22. | ||||||
|  |       inversion H12 as [n1]. inversion H22 as [n2]. | ||||||
|  |       rewrite <- H in H11. | ||||||
|  |       rewrite <- H0 in H21. | ||||||
|  |       exists (tm_const (plus n1 n2)). | ||||||
|  |       split. | ||||||
|  |         SCase "l". | ||||||
|  |           apply rsc_trans with (tm_plus (tm_const n1) t2). | ||||||
|  |           apply stepmany_congr_1. apply H11. | ||||||
|  |           apply rsc_trans with  | ||||||
|  |              (tm_plus (tm_const n1) (tm_const n2)). | ||||||
|  |           apply stepmany_congr2. apply v_const. apply H21. | ||||||
|  |           apply rsc_R. apply ST_PlusConstConst. | ||||||
|  |         SCase "r". | ||||||
|  |           rewrite nf_same_as_value. apply v_const. Qed. | ||||||
|  |            | ||||||
|  |  Lemma eval__value : forall t1 t2, | ||||||
|  |       eval t1 t2 -> | ||||||
|  |       value t2. | ||||||
|  |  Proof. | ||||||
|  |    intros t1 t2 HE. | ||||||
|  |    eval_cases (inversion HE) Case; apply v_const. Qed. | ||||||
|  |     | ||||||
|  |  | ||||||
|  |    (* | ||||||
|  | Theorem eval__stepmany: forall t v, | ||||||
|  |   eval t v -> t ===>* v. | ||||||
|  | Proof.    | ||||||
|  | *) | ||||||
							
								
								
									
										10
									
								
								samples/coq/Sorting.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								samples/coq/Sorting.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | (************************************************************************) | ||||||
|  | (*  v      *   The Coq Proof Assistant  /  The Coq Development Team     *) | ||||||
|  | (* <O___,, *   INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010     *) | ||||||
|  | (*   \VV/  **************************************************************) | ||||||
|  | (*    //   *      This file is distributed under the terms of the       *) | ||||||
|  | (*         *       GNU Lesser General Public License Version 2.1        *) | ||||||
|  | (************************************************************************) | ||||||
|  |  | ||||||
|  | Require Export Sorted. | ||||||
|  | Require Export Mergesort. | ||||||
							
								
								
									
										733
									
								
								samples/coq/Stlc.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										733
									
								
								samples/coq/Stlc.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,733 @@ | |||||||
|  |  | ||||||
|  | Require Export SfLib. | ||||||
|  |  | ||||||
|  | Module STLC. | ||||||
|  |  | ||||||
|  | Inductive ty : Type := | ||||||
|  |    | ty_Bool : ty | ||||||
|  |    | ty_arrow : ty -> ty -> ty. | ||||||
|  |  | ||||||
|  | Inductive tm : Type := | ||||||
|  |    | tm_var : id -> tm | ||||||
|  |    | tm_app : tm -> tm -> tm | ||||||
|  |    | tm_abs : id -> ty -> tm -> tm | ||||||
|  |    | tm_true : tm | ||||||
|  |    | tm_false : tm | ||||||
|  |    | tm_if : tm -> tm -> tm -> tm. | ||||||
|  |  | ||||||
|  | Tactic Notation "tm_cases" tactic(first) ident(c) := | ||||||
|  |   first; | ||||||
|  |   [ Case_aux c "tm_var" | Case_aux c "tm_app"  | ||||||
|  |   | Case_aux c "tm_abs" | Case_aux c "tm_true"  | ||||||
|  |   | Case_aux c "tm_false" | Case_aux c "tm_if" ]. | ||||||
|  |    | ||||||
|  | Notation a := (Id 0). | ||||||
|  | Notation b := (Id 1). | ||||||
|  | Notation c := (Id 2). | ||||||
|  |  | ||||||
|  | Notation idB := | ||||||
|  |    (tm_abs a ty_Bool (tm_var a)). | ||||||
|  |     | ||||||
|  | Notation idBB := | ||||||
|  |    (tm_abs a (ty_arrow ty_Bool ty_Bool) (tm_var a)). | ||||||
|  |     | ||||||
|  | Notation idBBBB := | ||||||
|  |    (tm_abs a (ty_arrow (ty_arrow ty_Bool ty_Bool)  | ||||||
|  |                          (ty_arrow ty_Bool ty_Bool))  | ||||||
|  |        (tm_var a)). | ||||||
|  |         | ||||||
|  | Notation k := (tm_abs a ty_Bool (tm_abs b ty_Bool (tm_var a))). | ||||||
|  |  | ||||||
|  | Inductive value : tm -> Prop := | ||||||
|  |   | v_abs : forall x T t, | ||||||
|  |       value (tm_abs x T t) | ||||||
|  |   | t_true :  | ||||||
|  |       value tm_true | ||||||
|  |   | t_false :  | ||||||
|  |       value tm_false. | ||||||
|  |  | ||||||
|  | Hint Constructors value. | ||||||
|  |  | ||||||
|  | Fixpoint subst (s:tm) (x:id) (t:tm) : tm := | ||||||
|  |    match t with | ||||||
|  |    | tm_var x' => if beq_id x x' then s else t | ||||||
|  |    | tm_abs x' T t1 => tm_abs x' T (if beq_id x x' then t1 else (subst s x t1)) | ||||||
|  |    | tm_app t1 t2 => tm_app (subst s x t1) (subst s x t2) | ||||||
|  |    | tm_true => tm_true | ||||||
|  |    | tm_false => tm_false | ||||||
|  |    | tm_if t1 t2 t3 => tm_if (subst s x t1) (subst s x t2) (subst s x t3) | ||||||
|  | end. | ||||||
|  |  | ||||||
|  | Reserved Notation "t1 '==>' t2" (at level 40). | ||||||
|  |  | ||||||
|  | Inductive step : tm -> tm -> Prop := | ||||||
|  |  | ST_AppAbs : forall x T t12 v2, | ||||||
|  |         value v2 -> | ||||||
|  |         (tm_app (tm_abs x T t12) v2) ==> (subst v2 x t12) | ||||||
|  |  | ST_App1 : forall t1 t1' t2, | ||||||
|  |         t1 ==> t1' -> | ||||||
|  |         tm_app t1 t2 ==> tm_app t1' t2 | ||||||
|  |  | ST_App2 : forall v1 t2 t2', | ||||||
|  |         value v1 -> | ||||||
|  |         t2 ==> t2' -> | ||||||
|  |         tm_app v1 t2 ==> tm_app v1 t2' | ||||||
|  |  | ST_IfTrue : forall t1 t2, | ||||||
|  |      (tm_if tm_true t1 t2) ==> t1 | ||||||
|  |  | ST_IfFalse : forall t1 t2, | ||||||
|  |      (tm_if tm_false t1 t2) ==> t2 | ||||||
|  |  | ST_If : forall t1 t1' t2 t3, | ||||||
|  |      t1 ==> t1' -> | ||||||
|  |      (tm_if t1 t2 t3) ==> (tm_if t1' t2 t3) | ||||||
|  |  | ||||||
|  | where "t1 '==>' t2" := (step t1 t2). | ||||||
|  |  | ||||||
|  | Tactic Notation "step_cases" tactic(first) ident(c) := | ||||||
|  |  first; | ||||||
|  |  [ Case_aux c "ST_AppAbs" | Case_aux c "ST_App1"  | ||||||
|  |  | Case_aux c "ST_App2" | Case_aux c "ST_IfTrue"  | ||||||
|  |  | Case_aux c "ST_IfFalse" | Case_aux c "ST_If" ]. | ||||||
|  |  | ||||||
|  | Notation stepmany := (refl_step_closure step). | ||||||
|  | Notation "t1 '==>*' t2" := (stepmany t1 t2) (at level 40). | ||||||
|  |  | ||||||
|  | Hint Constructors step. | ||||||
|  |  | ||||||
|  | Lemma step_example3 : | ||||||
|  |        (tm_app (tm_app idBBBB idBB) idB) | ||||||
|  |   ==>* idB. | ||||||
|  | Proof. | ||||||
|  |  eapply rsc_step. | ||||||
|  |  apply ST_App1. | ||||||
|  |  apply ST_AppAbs. | ||||||
|  |  apply v_abs. | ||||||
|  |   | ||||||
|  |  simpl. | ||||||
|  |  eapply rsc_step. | ||||||
|  |   apply ST_AppAbs. | ||||||
|  |   apply v_abs. | ||||||
|  |    | ||||||
|  |   simpl. | ||||||
|  |   apply rsc_refl. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Definition context := partial_map ty. | ||||||
|  | Module Context. | ||||||
|  |  | ||||||
|  | Definition partial_map (A:Type) := id -> option A. | ||||||
|  | Definition empty {A:Type} : partial_map A := (fun _ => None). | ||||||
|  | Definition extend {A:Type} (Gamma : partial_map A) (x:id) (T : A) := | ||||||
|  |    fun x' => if beq_id x x' then Some T else Gamma x'. | ||||||
|  |     | ||||||
|  | Lemma extend_eq : forall A (ctxt: partial_map A) x T, | ||||||
|  |    (extend ctxt x T) x = Some T. | ||||||
|  | Proof. | ||||||
|  |    intros. unfold extend. rewrite <- beq_id_refl. auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma extend_neq : forall A (ctxt: partial_map A) x1 T x2, | ||||||
|  |    beq_id x2 x1 = false -> | ||||||
|  |       (extend ctxt x2 T) x1 = ctxt x1. | ||||||
|  | Proof. | ||||||
|  | intros. unfold extend. rewrite H. auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | End Context. | ||||||
|  |  | ||||||
|  | Inductive has_type : context -> tm -> ty -> Prop := | ||||||
|  |    | T_Var : forall Gamma x T, | ||||||
|  |       Gamma x = Some T -> | ||||||
|  |          has_type Gamma (tm_var x) T | ||||||
|  |    | T_Abs : forall Gamma x T11 T12 t12, | ||||||
|  |       has_type (extend Gamma x T11) t12 T12 -> | ||||||
|  |          has_type Gamma (tm_abs x T11 t12) (ty_arrow T11 T12) | ||||||
|  |    | T_App : forall T11 T12 Gamma t1 t2, | ||||||
|  |       has_type Gamma t1 (ty_arrow T11 T12) -> | ||||||
|  |          has_type Gamma t2 T11 -> | ||||||
|  |             has_type Gamma (tm_app t1 t2) T12 | ||||||
|  |    | T_True : forall Gamma, | ||||||
|  |       has_type Gamma tm_true ty_Bool | ||||||
|  |    | T_False : forall Gamma, | ||||||
|  |       has_type Gamma tm_false ty_Bool | ||||||
|  |    | T_If : forall t1 t2 t3 T Gamma, | ||||||
|  |       has_type Gamma t1 ty_Bool -> | ||||||
|  |       has_type Gamma t2 T -> | ||||||
|  |       has_type Gamma t3 T -> | ||||||
|  |       has_type Gamma (tm_if t1 t2 t3) T. | ||||||
|  |        | ||||||
|  | Tactic Notation "has_type_cases" tactic(first) ident(c) := | ||||||
|  |   first; | ||||||
|  |   [ Case_aux c "T_Var" | Case_aux c "T_Abs"  | ||||||
|  |   | Case_aux c "T_App" | Case_aux c "T_True"  | ||||||
|  |   | Case_aux c "T_False" | Case_aux c "T_If" ]. | ||||||
|  |  | ||||||
|  | Hint Constructors has_type. | ||||||
|  |  | ||||||
|  | Hint Unfold beq_id beq_nat extend. | ||||||
|  |  | ||||||
|  | Example typing_example_2_full : | ||||||
|  |   has_type empty | ||||||
|  |     (tm_abs a ty_Bool | ||||||
|  |        (tm_abs b (ty_arrow ty_Bool ty_Bool) | ||||||
|  |           (tm_app (tm_var b) (tm_app (tm_var b) (tm_var a))))) | ||||||
|  |     (ty_arrow ty_Bool (ty_arrow (ty_arrow ty_Bool ty_Bool) ty_Bool)). | ||||||
|  | Proof. | ||||||
|  | apply T_Abs. | ||||||
|  | apply T_Abs. | ||||||
|  | apply T_App with (T11 := ty_Bool). | ||||||
|  |  apply T_Var. | ||||||
|  |  unfold extend. | ||||||
|  |  simpl. | ||||||
|  |  reflexivity. | ||||||
|  |   | ||||||
|  |  apply T_App with (T11 := ty_Bool). | ||||||
|  |   apply T_Var. | ||||||
|  |   unfold extend. | ||||||
|  |   simpl. | ||||||
|  |   reflexivity. | ||||||
|  |    | ||||||
|  |   apply T_Var. | ||||||
|  |   unfold extend. | ||||||
|  |   simpl. | ||||||
|  |   reflexivity. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Example typing_example_3 : | ||||||
|  |   exists T,  | ||||||
|  |     has_type empty | ||||||
|  |       (tm_abs a (ty_arrow ty_Bool ty_Bool) | ||||||
|  |          (tm_abs b (ty_arrow ty_Bool ty_Bool) | ||||||
|  |             (tm_abs c ty_Bool | ||||||
|  |                (tm_app (tm_var b) (tm_app (tm_var a) (tm_var c)))))) | ||||||
|  |       T. | ||||||
|  |  | ||||||
|  | Proof with auto. | ||||||
|  | exists | ||||||
|  |  (ty_arrow (ty_arrow ty_Bool ty_Bool) | ||||||
|  |     (ty_arrow (ty_arrow ty_Bool ty_Bool) (ty_arrow ty_Bool ty_Bool))). | ||||||
|  | apply T_Abs. | ||||||
|  | apply T_Abs. | ||||||
|  | apply T_Abs. | ||||||
|  | apply T_App with (T11 := ty_Bool). | ||||||
|  |  apply T_Var. | ||||||
|  |  unfold extend. | ||||||
|  |  simpl. | ||||||
|  |  reflexivity. | ||||||
|  |   | ||||||
|  |  apply T_App with (T11 := ty_Bool). | ||||||
|  |   auto. | ||||||
|  |    | ||||||
|  |   auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Theorem coiso : forall a b e, | ||||||
|  |    a ==>* b -> | ||||||
|  |       tm_app a e ==>* tm_app b e. | ||||||
|  | Proof. | ||||||
|  | intros. | ||||||
|  | induction H. | ||||||
|  |  apply rsc_refl. | ||||||
|  |   | ||||||
|  |  apply rsc_step with (tm_app y e). | ||||||
|  |   apply ST_App1. | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem reptrans : forall a b c, | ||||||
|  |    a ==>* b -> | ||||||
|  |       b ==>* c -> | ||||||
|  |          a ==>* c. | ||||||
|  | Proof. | ||||||
|  |  | ||||||
|  | intros a b c H. | ||||||
|  | induction H. | ||||||
|  |  intros. | ||||||
|  |  assumption. | ||||||
|  |   | ||||||
|  |  intros H1. | ||||||
|  |  apply IHrefl_step_closure in H1. | ||||||
|  |  apply rsc_step with y. | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | (* TODO | ||||||
|  | Example typing_nonexample_3 : | ||||||
|  |   ~ (exists S, exists T, | ||||||
|  |         has_type empty  | ||||||
|  |           (tm_abs a S | ||||||
|  |              (tm_app (tm_var a) (tm_var a))) | ||||||
|  |           T). | ||||||
|  | Proof. | ||||||
|  | *) | ||||||
|  |  | ||||||
|  | Inductive appears_free_in : id -> tm -> Prop := | ||||||
|  |   | afi_var : forall x, | ||||||
|  |       appears_free_in x (tm_var x) | ||||||
|  |   | afi_app1 : forall x t1 t2, | ||||||
|  |       appears_free_in x t1 -> appears_free_in x (tm_app t1 t2) | ||||||
|  |   | afi_app2 : forall x t1 t2, | ||||||
|  |       appears_free_in x t2 -> appears_free_in x (tm_app t1 t2) | ||||||
|  |   | afi_abs : forall x y T11 t12, | ||||||
|  |       y <> x -> | ||||||
|  |       appears_free_in x t12 -> | ||||||
|  |       appears_free_in x (tm_abs y T11 t12) | ||||||
|  |   | afi_if1 : forall x t1 t2 t3, | ||||||
|  |       appears_free_in x t1 -> | ||||||
|  |       appears_free_in x (tm_if t1 t2 t3) | ||||||
|  |   | afi_if2 : forall x t1 t2 t3, | ||||||
|  |       appears_free_in x t2 -> | ||||||
|  |       appears_free_in x (tm_if t1 t2 t3) | ||||||
|  |   | afi_if3 : forall x t1 t2 t3, | ||||||
|  |       appears_free_in x t3 -> | ||||||
|  |       appears_free_in x (tm_if t1 t2 t3). | ||||||
|  |        | ||||||
|  | Tactic Notation "afi_cases" tactic(first) ident(c) := | ||||||
|  |   first; | ||||||
|  |   [ Case_aux c "afi_var" | ||||||
|  |   | Case_aux c "afi_app1" | Case_aux c "afi_app2"  | ||||||
|  |   | Case_aux c "afi_abs"  | ||||||
|  |   | Case_aux c "afi_if1" | Case_aux c "afi_if2"  | ||||||
|  |   | Case_aux c "afi_if3" ]. | ||||||
|  |  | ||||||
|  | Hint Constructors appears_free_in. | ||||||
|  |  | ||||||
|  | Definition closed (t:tm) := | ||||||
|  |   forall x, ~ appears_free_in x t. | ||||||
|  |    | ||||||
|  | Lemma free_in_context : forall x t T Gamma, | ||||||
|  |   appears_free_in x t -> | ||||||
|  |   has_type Gamma t T -> | ||||||
|  |   exists T', Gamma x = Some T'. | ||||||
|  | Proof. | ||||||
|  |   intros. generalize dependent Gamma. generalize dependent T. | ||||||
|  |   afi_cases (induction H) Case;  | ||||||
|  |          intros; try solve [inversion H0; eauto]. | ||||||
|  |   Case "afi_abs". | ||||||
|  |     inversion H1; subst. | ||||||
|  |     apply IHappears_free_in in H7. | ||||||
|  |     apply not_eq_beq_id_false in H. | ||||||
|  |     rewrite extend_neq in H7; assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Corollary typable_empty__closed : forall t T,  | ||||||
|  |     has_type empty t T -> | ||||||
|  |     closed t. | ||||||
|  | Proof. | ||||||
|  | intros t T H x H1. | ||||||
|  | remember (@empty ty) as Gamma. | ||||||
|  | assert (exists t' : _, Gamma x = Some t'). | ||||||
|  |  apply free_in_context with (t := t) (T := T). | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |  inversion H0. | ||||||
|  |  rewrite HeqGamma in H2. | ||||||
|  |  inversion H2. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma context_invariance : forall Gamma Gamma' t S, | ||||||
|  |      has_type Gamma t S -> | ||||||
|  |      (forall x, appears_free_in x t -> Gamma x = Gamma' x) -> | ||||||
|  |      has_type Gamma' t S. | ||||||
|  | Proof with auto. | ||||||
|  | intros. | ||||||
|  | generalize dependent Gamma'. | ||||||
|  | has_type_cases (induction H) Case; intros; auto. | ||||||
|  |  apply T_Var. | ||||||
|  |  rewrite <- H0... | ||||||
|  |   | ||||||
|  |  apply T_Abs. | ||||||
|  |  apply IHhas_type. | ||||||
|  |  intros x0 Hafi. | ||||||
|  |  unfold extend. | ||||||
|  |  remember (beq_id x x0) as e. | ||||||
|  |  destruct e. | ||||||
|  |   reflexivity. | ||||||
|  |    | ||||||
|  |   auto. | ||||||
|  |   apply H0. | ||||||
|  |   apply afi_abs. | ||||||
|  |    auto. | ||||||
|  |    eauto   . | ||||||
|  |    apply beq_id_false_not_eq. | ||||||
|  |    rewrite Heqe. | ||||||
|  |    reflexivity. | ||||||
|  |     | ||||||
|  |    assumption. | ||||||
|  |     | ||||||
|  |  apply T_App with T11. | ||||||
|  |   auto. | ||||||
|  |    | ||||||
|  |   auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Lemma substitution_preserves_typing : forall Gamma x U v t T, | ||||||
|  |    has_type (extend Gamma x U) t T -> | ||||||
|  |       has_type empty v U -> | ||||||
|  |          has_type Gamma (subst v x t) T. | ||||||
|  | Proof with eauto. | ||||||
|  |    intros Gamma x U v t T Ht Hv. | ||||||
|  |    generalize dependent Gamma. | ||||||
|  |    generalize dependent T. | ||||||
|  |    tm_cases (induction t) Case; intros T Gamma H; inversion H; subst; simpl... | ||||||
|  |    Case "tm_var". | ||||||
|  |        rename i into y. remember (beq_id x y) as e. destruct e. | ||||||
|  |        SCase "x=y". | ||||||
|  |          apply beq_id_eq in Heqe. subst. | ||||||
|  |          rewrite extend_eq in H2. | ||||||
|  |          inversion H2; subst. | ||||||
|  |          clear H2. | ||||||
|  |            eapply context_invariance... | ||||||
|  |            intros x Hcontra. | ||||||
|  |            destruct (free_in_context _ _ T empty Hcontra) as (T', HT')... | ||||||
|  |            inversion HT'. | ||||||
|  |  | ||||||
|  |            apply T_Var. | ||||||
|  |            rewrite extend_neq in H2. | ||||||
|  |             assumption. | ||||||
|  |  | ||||||
|  |             rewrite Heqe. | ||||||
|  |             reflexivity. | ||||||
|  |  | ||||||
|  |           rename i into y. | ||||||
|  |           apply T_Abs. | ||||||
|  |           remember (beq_id x y) as e. | ||||||
|  |           destruct e. | ||||||
|  |            eapply context_invariance... | ||||||
|  |            apply beq_id_eq in Heqe. | ||||||
|  |            subst. | ||||||
|  |            intros x Hafi. | ||||||
|  |            unfold extend. | ||||||
|  |            destruct (beq_id y x). | ||||||
|  |             reflexivity. | ||||||
|  |  | ||||||
|  |             reflexivity. | ||||||
|  |  | ||||||
|  |            apply IHt. | ||||||
|  |            eapply context_invariance... | ||||||
|  |            intros x0 Hafi. | ||||||
|  |            unfold extend. | ||||||
|  |            remember (beq_id y x0) as Coiso1. | ||||||
|  |            remember (beq_id x x0) as Coiso2. | ||||||
|  |            destruct Coiso1. | ||||||
|  |             auto. | ||||||
|  |             eauto   . | ||||||
|  |             destruct Coiso2. | ||||||
|  |              eauto   . | ||||||
|  |              auto. | ||||||
|  |              apply beq_id_eq in HeqCoiso1. | ||||||
|  |              apply beq_id_eq in HeqCoiso2. | ||||||
|  |              subst. | ||||||
|  |              assert (x0 <> x0). | ||||||
|  |               apply beq_id_false_not_eq. | ||||||
|  |               rewrite Heqe. | ||||||
|  |               auto. | ||||||
|  |  | ||||||
|  |               apply ex_falso_quodlibet. | ||||||
|  |               apply H0. | ||||||
|  |               reflexivity. | ||||||
|  |  | ||||||
|  |              reflexivity. | ||||||
|  |  | ||||||
|  |             destruct Coiso2. | ||||||
|  |              auto. | ||||||
|  |  | ||||||
|  |              auto. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem preservation : forall t t' T, | ||||||
|  |      has_type empty t T -> | ||||||
|  |      t ==> t' -> | ||||||
|  |      has_type empty t' T. | ||||||
|  | Proof. | ||||||
|  | remember (@empty ty) as Gamma. | ||||||
|  | intros t t' T HT. | ||||||
|  | generalize dependent t'. | ||||||
|  | induction HT. | ||||||
|  |  intros t' H1. | ||||||
|  |  inversion H1. | ||||||
|  |   | ||||||
|  |  intros t' H1. | ||||||
|  |  inversion H1. | ||||||
|  |   | ||||||
|  |  intros t' H1. | ||||||
|  |  inversion H1. | ||||||
|  |   apply substitution_preserves_typing with T11. | ||||||
|  |    subst. | ||||||
|  |    inversion HT1. | ||||||
|  |    subst. | ||||||
|  |    apply H2. | ||||||
|  |     | ||||||
|  |    subst. | ||||||
|  |    assumption. | ||||||
|  |     | ||||||
|  |   subst. | ||||||
|  |   apply T_App with T11. | ||||||
|  |    apply IHHT1. | ||||||
|  |     reflexivity. | ||||||
|  |      | ||||||
|  |     assumption. | ||||||
|  |      | ||||||
|  |    assumption. | ||||||
|  |     | ||||||
|  |   subst. | ||||||
|  |   apply T_App with T11. | ||||||
|  |    assumption. | ||||||
|  |     | ||||||
|  |    apply IHHT2. | ||||||
|  |     reflexivity. | ||||||
|  |      | ||||||
|  |     assumption. | ||||||
|  |      | ||||||
|  |  intros t' H. | ||||||
|  |  inversion H. | ||||||
|  |   | ||||||
|  |  intros t' H. | ||||||
|  |  inversion H. | ||||||
|  |   | ||||||
|  |  intros t' H. | ||||||
|  |  inversion H. | ||||||
|  |   subst. | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   subst. | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   subst. | ||||||
|  |   apply T_If. | ||||||
|  |    apply IHHT1. | ||||||
|  |     reflexivity. | ||||||
|  |      | ||||||
|  |     assumption. | ||||||
|  |      | ||||||
|  |    assumption. | ||||||
|  |     | ||||||
|  |    assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem progress : forall t T, | ||||||
|  |      has_type empty t T -> | ||||||
|  |      value t \/ exists t', t ==> t'. | ||||||
|  | Proof. | ||||||
|  | intros t T. | ||||||
|  | intros H. | ||||||
|  | remember (@empty ty) as Gamma. | ||||||
|  | induction H. | ||||||
|  |  rewrite HeqGamma in H. | ||||||
|  |  unfold empty in H. | ||||||
|  |  inversion H. | ||||||
|  |   | ||||||
|  |  left. | ||||||
|  |  apply v_abs. | ||||||
|  |   | ||||||
|  |  right. | ||||||
|  |  assert (value t1 \/ (exists t' : tm, t1 ==> t')). | ||||||
|  |   apply IHhas_type1. | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   assert (value t2 \/ (exists t' : tm, t2 ==> t')). | ||||||
|  |    apply IHhas_type2. | ||||||
|  |    assumption. | ||||||
|  |     | ||||||
|  |    inversion H1. | ||||||
|  |     inversion H2. | ||||||
|  |      inversion H3. | ||||||
|  |       subst. | ||||||
|  |       exists (subst t2 x t). | ||||||
|  |       apply ST_AppAbs. | ||||||
|  |       assumption. | ||||||
|  |        | ||||||
|  |       subst. | ||||||
|  |       inversion H. | ||||||
|  |        | ||||||
|  |       subst. | ||||||
|  |       inversion H. | ||||||
|  |        | ||||||
|  |      inversion H4. | ||||||
|  |      exists (tm_app t1 x). | ||||||
|  |      apply ST_App2. | ||||||
|  |       assumption. | ||||||
|  |        | ||||||
|  |       assumption. | ||||||
|  |        | ||||||
|  |     inversion H3. | ||||||
|  |     exists (tm_app x t2). | ||||||
|  |     apply ST_App1. | ||||||
|  |     assumption. | ||||||
|  |      | ||||||
|  |  left. | ||||||
|  |  auto. | ||||||
|  |   | ||||||
|  |  left. | ||||||
|  |  auto. | ||||||
|  |   | ||||||
|  |  right. | ||||||
|  |  assert (value t1 \/ (exists t' : tm, t1 ==> t')). | ||||||
|  |   apply IHhas_type1. | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   inversion H2. | ||||||
|  |    inversion H3. | ||||||
|  |     subst. | ||||||
|  |     inversion H. | ||||||
|  |      | ||||||
|  |     subst. | ||||||
|  |     exists t2. | ||||||
|  |     apply ST_IfTrue. | ||||||
|  |      | ||||||
|  |     subst. | ||||||
|  |     exists t3. | ||||||
|  |     apply ST_IfFalse. | ||||||
|  |      | ||||||
|  |    inversion H3. | ||||||
|  |    exists (tm_if x t2 t3). | ||||||
|  |    apply ST_If. | ||||||
|  |    assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem progress' : forall t T, | ||||||
|  |      has_type empty t T -> | ||||||
|  |      value t \/ exists t', t ==> t'. | ||||||
|  | Proof. | ||||||
|  | intros t. | ||||||
|  | tm_cases (induction t) Case; intros T Ht; auto. | ||||||
|  |  inversion Ht. | ||||||
|  |  inversion H1. | ||||||
|  |   | ||||||
|  |  right. | ||||||
|  |  inversion Ht. | ||||||
|  |  subst. | ||||||
|  |  assert (value t1 \/ (exists t' : tm, t1 ==> t')). | ||||||
|  |   apply IHt1 with (T := ty_arrow T11 T). | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   assert (value t2 \/ (exists t' : tm, t2 ==> t')). | ||||||
|  |    apply IHt2 with T11. | ||||||
|  |    assumption. | ||||||
|  |     | ||||||
|  |    inversion H. | ||||||
|  |     inversion H1. | ||||||
|  |      subst. | ||||||
|  |      inversion H0. | ||||||
|  |       exists (subst t2 x t). | ||||||
|  |       apply ST_AppAbs. | ||||||
|  |       assumption. | ||||||
|  |        | ||||||
|  |       inversion H3. | ||||||
|  |       exists (tm_app (tm_abs x T0 t) x0). | ||||||
|  |       apply ST_App2. | ||||||
|  |        assumption. | ||||||
|  |         | ||||||
|  |        assumption. | ||||||
|  |         | ||||||
|  |      subst. | ||||||
|  |      inversion H2. | ||||||
|  |       | ||||||
|  |      subst. | ||||||
|  |      inversion H2. | ||||||
|  |       | ||||||
|  |     inversion H1. | ||||||
|  |     exists (tm_app x t2). | ||||||
|  |     apply ST_App1. | ||||||
|  |     assumption. | ||||||
|  |      | ||||||
|  |  right. | ||||||
|  |  inversion Ht. | ||||||
|  |  subst. | ||||||
|  |  assert (value t1 \/ (exists t' : tm, t1 ==> t')). | ||||||
|  |   apply IHt1 with ty_Bool. | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   assert (value t2 \/ (exists t' : tm, t2 ==> t')). | ||||||
|  |    apply IHt2 with T. | ||||||
|  |    assumption. | ||||||
|  |     | ||||||
|  |    assert (value t3 \/ (exists t' : tm, t3 ==> t')). | ||||||
|  |     apply IHt3 with T. | ||||||
|  |     assumption. | ||||||
|  |      | ||||||
|  |     inversion H. | ||||||
|  |      inversion H2. | ||||||
|  |       subst. | ||||||
|  |       inversion H3. | ||||||
|  |        | ||||||
|  |       subst. | ||||||
|  |       subst. | ||||||
|  |       exists t2. | ||||||
|  |       apply ST_IfTrue. | ||||||
|  |        | ||||||
|  |       exists t3. | ||||||
|  |       apply ST_IfFalse. | ||||||
|  |        | ||||||
|  |      inversion H2. | ||||||
|  |      exists (tm_if x t2 t3). | ||||||
|  |      apply ST_If. | ||||||
|  |      assumption. | ||||||
|  | Qed. | ||||||
|  |  | ||||||
|  | Theorem types_unique : forall t T Gamma, | ||||||
|  |    has_type Gamma t T -> | ||||||
|  |       (forall T', has_type Gamma t T' -> T' = T). | ||||||
|  | Proof. | ||||||
|  | intros t T Gamma H. | ||||||
|  | induction H. | ||||||
|  |  intros T'. | ||||||
|  |  intros H1. | ||||||
|  |  inversion H1. | ||||||
|  |  subst. | ||||||
|  |  subst. | ||||||
|  |  auto. | ||||||
|  |  eauto   . | ||||||
|  |  inversion H1. | ||||||
|  |  subst. | ||||||
|  |  assert (Some T = Some T'). | ||||||
|  |   rewrite <- H3. | ||||||
|  |   rewrite <- H. | ||||||
|  |   reflexivity. | ||||||
|  |    | ||||||
|  |   inversion H0. | ||||||
|  |   reflexivity. | ||||||
|  |    | ||||||
|  |  intros T'. | ||||||
|  |  intros H1. | ||||||
|  |  inversion H1. | ||||||
|  |  subst. | ||||||
|  |  assert (T1 = T12). | ||||||
|  |   apply IHhas_type. | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   rewrite H0. | ||||||
|  |   reflexivity. | ||||||
|  |    | ||||||
|  |  intros T' H1. | ||||||
|  |  subst. | ||||||
|  |  inversion H1. | ||||||
|  |  subst. | ||||||
|  |  assert (ty_arrow T0 T' = ty_arrow T11 T12). | ||||||
|  |   apply IHhas_type1. | ||||||
|  |   assumption. | ||||||
|  |    | ||||||
|  |   inversion H2. | ||||||
|  |   reflexivity. | ||||||
|  |    | ||||||
|  |  intros T'. | ||||||
|  |  intros H. | ||||||
|  |  inversion H. | ||||||
|  |  reflexivity. | ||||||
|  |   | ||||||
|  |  intros. | ||||||
|  |  inversion H. | ||||||
|  |  reflexivity. | ||||||
|  |   | ||||||
|  |  intros T'. | ||||||
|  |  intros H2. | ||||||
|  |  inversion H2. | ||||||
|  |  subst. | ||||||
|  |  apply IHhas_type2. | ||||||
|  |  assumption. | ||||||
|  | Qed. | ||||||
							
								
								
									
										94
									
								
								samples/verilog/button_debounce.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										94
									
								
								samples/verilog/button_debounce.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Original Author: Schuyler Eldridge | ||||||
|  | // Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com) | ||||||
|  | // button_debounce.v | ||||||
|  | // Created: 10/10/2009 | ||||||
|  | // Modified: 3/20/2012 | ||||||
|  | // | ||||||
|  | // Counter based debounce circuit originally written for EC551 (back | ||||||
|  | // in the day) and then modified (i.e. chagned entirely) into 3 always | ||||||
|  | // block format. This debouncer generates a signal that goes high for | ||||||
|  | // 1 clock cycle after the clock sees an asserted value on the button | ||||||
|  | // line. This action is then disabled until the counter hits a | ||||||
|  | // specified count value that is determined by the clock frequency and | ||||||
|  | // desired debounce frequency. An alternative implementation would not | ||||||
|  | // use a counter, but would use the shift register approach, looking | ||||||
|  | // for repeated matches (say 5) on the button line. | ||||||
|  | //  | ||||||
|  | // Copyright (C) 2012 Schuyler Eldridge, Boston University | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | `timescale 1ns / 1ps | ||||||
|  | module button_debounce | ||||||
|  |   ( | ||||||
|  |    input      clk,     // clock | ||||||
|  |    input      reset_n, // asynchronous reset  | ||||||
|  |    input      button,  // bouncy button | ||||||
|  |    output reg debounce // debounced 1-cycle signal | ||||||
|  |    ); | ||||||
|  |    | ||||||
|  |   parameter | ||||||
|  |     CLK_FREQUENCY  = 66000000, | ||||||
|  |     DEBOUNCE_HZ    = 2; | ||||||
|  |   // These parameters are specified such that you can choose any power | ||||||
|  |   // of 2 frequency for a debouncer between 1 Hz and | ||||||
|  |   // CLK_FREQUENCY. Note, that this will throw errors if you choose a | ||||||
|  |   // non power of 2 frequency (i.e. count_value evaluates to some | ||||||
|  |   // number / 3 which isn't interpreted as a logical right shift). I'm | ||||||
|  |   // assuming this will not work for DEBOUNCE_HZ values less than 1, | ||||||
|  |   // however, I'm uncertain of the value of a debouncer for fractional | ||||||
|  |   // hertz button presses. | ||||||
|  |   localparam | ||||||
|  |     COUNT_VALUE  = CLK_FREQUENCY / DEBOUNCE_HZ, | ||||||
|  |     WAIT         = 0, | ||||||
|  |     FIRE         = 1, | ||||||
|  |     COUNT        = 2; | ||||||
|  |  | ||||||
|  |   reg [1:0]   state, next_state; | ||||||
|  |   reg [25:0]  count; | ||||||
|  |    | ||||||
|  |   always @ (posedge clk or negedge reset_n) | ||||||
|  |     state <= (!reset_n) ? WAIT : next_state; | ||||||
|  |  | ||||||
|  |   always @ (posedge clk or negedge reset_n) begin | ||||||
|  |     if (!reset_n) begin | ||||||
|  |       debounce <= 0; | ||||||
|  |       count    <= 0; | ||||||
|  |     end | ||||||
|  |     else begin | ||||||
|  |       debounce <= 0; | ||||||
|  |       count    <= 0; | ||||||
|  |       case (state) | ||||||
|  |         WAIT: begin | ||||||
|  |         end | ||||||
|  |         FIRE: begin | ||||||
|  |           debounce <= 1; | ||||||
|  |         end | ||||||
|  |         COUNT: begin | ||||||
|  |           count <= count + 1; | ||||||
|  |         end | ||||||
|  |       endcase  | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   always @ * begin | ||||||
|  |     case (state) | ||||||
|  |       WAIT:    next_state = (button)                  ? FIRE : state; | ||||||
|  |       FIRE:    next_state = COUNT; | ||||||
|  |       COUNT:   next_state = (count > COUNT_VALUE - 1) ? WAIT : state; | ||||||
|  |       default: next_state = WAIT; | ||||||
|  |     endcase | ||||||
|  |   end | ||||||
|  |  | ||||||
|  | endmodule | ||||||
							
								
								
									
										155
									
								
								samples/verilog/control.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										155
									
								
								samples/verilog/control.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,155 @@ | |||||||
|  | `timescale 1ns / 1ps | ||||||
|  | // Copyright (C) 2008 Schuyler Eldridge, Boston University | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | module control(clk,en,dsp_sel,an); | ||||||
|  |         input clk, en; | ||||||
|  |         output [1:0]dsp_sel; | ||||||
|  |         output [3:0]an; | ||||||
|  |         wire a,b,c,d,e,f,g,h,i,j,k,l; | ||||||
|  |          | ||||||
|  |         assign an[3] = a; | ||||||
|  |         assign an[2] = b; | ||||||
|  |         assign an[1] = c; | ||||||
|  |         assign an[0] = d; | ||||||
|  |          | ||||||
|  |         assign dsp_sel[1] = e; | ||||||
|  |          | ||||||
|  |         assign dsp_sel[0] = i; | ||||||
|  |          | ||||||
|  |          | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b0) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF3( | ||||||
|  |                 .Q(a), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(d), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 ); | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b1) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF2( | ||||||
|  |                 .Q(b), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(a), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 ); | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b1) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF1( | ||||||
|  |                 .Q(c), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(b), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 ); | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b1) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF0( | ||||||
|  |                 .Q(d), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(c), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 ); | ||||||
|  |                  | ||||||
|  |                  | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b1) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF7( | ||||||
|  |                 .Q(e), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(h), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 ); | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b1) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF6( | ||||||
|  |                 .Q(f), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(e), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 );               | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b0) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF5( | ||||||
|  |                 .Q(g), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(f), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 ); | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b0) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF4( | ||||||
|  |                 .Q(h), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(g), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 ); | ||||||
|  |                  | ||||||
|  |                  | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b1) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF11( | ||||||
|  |                 .Q(i), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(l), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 ); | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b0) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF10( | ||||||
|  |                 .Q(j), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(i), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 );               | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b1) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF9( | ||||||
|  |                 .Q(k), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(j), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 ); | ||||||
|  |                 FDRSE #( | ||||||
|  |                 .INIT(1'b0) // Initial value of register (1'b0 or 1'b1) | ||||||
|  |                 ) DFF8( | ||||||
|  |                 .Q(l), // Data output | ||||||
|  |                 .C(clk), // Clock input | ||||||
|  |                 .CE(en), // Clock enable input | ||||||
|  |                 .D(k), // Data input | ||||||
|  |                 .R(1'b0), // Synchronous reset input | ||||||
|  |                 .S(1'b0) // Synchronous set input | ||||||
|  |                 ); | ||||||
|  | endmodule | ||||||
							
								
								
									
										54
									
								
								samples/verilog/hex_display.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										54
									
								
								samples/verilog/hex_display.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | /* | ||||||
|  |  *  Copyright (c) 2009  Zeus Gomez Marmolejo <zeus@opencores.org> | ||||||
|  |  * | ||||||
|  |  *  This file is part of the Zet processor. This processor is free | ||||||
|  |  *  hardware; you can redistribute it and/or modify it under the terms of | ||||||
|  |  *  the GNU General Public License as published by the Free Software | ||||||
|  |  *  Foundation; either version 3, or (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *  Zet is distrubuted in the hope that it will be useful, but WITHOUT | ||||||
|  |  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||||||
|  |  *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | ||||||
|  |  *  License for more details. | ||||||
|  |  * | ||||||
|  |  *  You should have received a copy of the GNU General Public License | ||||||
|  |  *  along with Zet; see the file COPYING. If not, see | ||||||
|  |  *  <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | module hex_display ( | ||||||
|  |     input  [15:0] num, | ||||||
|  |     input         en, | ||||||
|  |  | ||||||
|  |     output [6:0] hex0, | ||||||
|  |     output [6:0] hex1, | ||||||
|  |     output [6:0] hex2, | ||||||
|  |     output [6:0] hex3 | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   // Module instantiations | ||||||
|  |   seg_7 hex_group0 ( | ||||||
|  |     .num (num[3:0]), | ||||||
|  |     .en  (en), | ||||||
|  |     .seg (hex0) | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   seg_7 hex_group1 ( | ||||||
|  |     .num (num[7:4]), | ||||||
|  |     .en  (en), | ||||||
|  |     .seg (hex1) | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   seg_7 hex_group2 ( | ||||||
|  |     .num (num[11:8]), | ||||||
|  |     .en  (en), | ||||||
|  |     .seg (hex2) | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   seg_7 hex_group3 ( | ||||||
|  |     .num (num[15:12]), | ||||||
|  |     .en  (en), | ||||||
|  |     .seg (hex3) | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  | endmodule | ||||||
							
								
								
									
										45
									
								
								samples/verilog/mux.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										45
									
								
								samples/verilog/mux.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | `timescale 1ns / 1ps | ||||||
|  | // Copyright (C) 2008 Schuyler Eldridge, Boston University | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | module mux(opA,opB,sum,dsp_sel,out); | ||||||
|  | 	input [3:0] opA,opB; | ||||||
|  | 	input [4:0] sum; | ||||||
|  | 	input [1:0] dsp_sel; | ||||||
|  | 	output [3:0] out; | ||||||
|  | 	 | ||||||
|  | 	reg cout; | ||||||
|  | 	 | ||||||
|  | 	always @ (sum) | ||||||
|  | 		begin | ||||||
|  | 			if (sum[4] == 1) | ||||||
|  | 				cout <= 4'b0001; | ||||||
|  | 			else | ||||||
|  | 				cout <= 4'b0000; | ||||||
|  | 		end | ||||||
|  | 	 | ||||||
|  | 	reg out; | ||||||
|  | 	 | ||||||
|  | 	always @(dsp_sel,sum,cout,opB,opA) | ||||||
|  | 		begin | ||||||
|  | 			if (dsp_sel == 2'b00) | ||||||
|  | 				out <= sum[3:0]; | ||||||
|  | 			else if (dsp_sel == 2'b01) | ||||||
|  | 				out <= cout; | ||||||
|  | 			else if (dsp_sel == 2'b10) | ||||||
|  | 				out <= opB; | ||||||
|  | 			else if (dsp_sel == 2'b11) | ||||||
|  | 				out <= opA; | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | endmodule | ||||||
							
								
								
									
										82
									
								
								samples/verilog/pipeline_registers.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										82
									
								
								samples/verilog/pipeline_registers.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,82 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Original Author: Schuyler Eldridge | ||||||
|  | // Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com) | ||||||
|  | // pipeline_registers.v | ||||||
|  | // Created: 4.4.2012 | ||||||
|  | // Modified: 4.4.2012 | ||||||
|  | // | ||||||
|  | // Implements a series of pipeline registers specified by the input | ||||||
|  | // parameters BIT_WIDTH and NUMBER_OF_STAGES. BIT_WIDTH determines the | ||||||
|  | // size of the signal passed through each of the pipeline | ||||||
|  | // registers. NUMBER_OF_STAGES is the number of pipeline registers | ||||||
|  | // generated. This accepts values of 0 (yes, it just passes data from | ||||||
|  | // input to output...) up to however many stages specified. | ||||||
|  | // Copyright (C) 2012 Schuyler Eldridge, Boston University | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | `timescale 1ns / 1ps | ||||||
|  | module pipeline_registers | ||||||
|  |   ( | ||||||
|  |    input                      clk, | ||||||
|  |    input                      reset_n, | ||||||
|  |    input [BIT_WIDTH-1:0]      pipe_in, | ||||||
|  |    output reg [BIT_WIDTH-1:0] pipe_out | ||||||
|  |    ); | ||||||
|  |  | ||||||
|  |   // WARNING!!! THESE PARAMETERS ARE INTENDED TO BE MODIFIED IN A TOP | ||||||
|  |   // LEVEL MODULE. LOCAL CHANGES HERE WILL, MOST LIKELY, BE | ||||||
|  |   // OVERWRITTEN! | ||||||
|  |   parameter  | ||||||
|  |     BIT_WIDTH         = 10, | ||||||
|  |     NUMBER_OF_STAGES  = 5; | ||||||
|  |  | ||||||
|  |   // Main generate function for conditional hardware instantiation | ||||||
|  |   generate | ||||||
|  |     genvar                                 i; | ||||||
|  |     // Pass-through case for the odd event that no pipeline stages are | ||||||
|  |     // specified. | ||||||
|  |     if (NUMBER_OF_STAGES == 0) begin | ||||||
|  |       always @ * | ||||||
|  |         pipe_out = pipe_in; | ||||||
|  |     end | ||||||
|  |     // Single flop case for a single stage pipeline | ||||||
|  |     else if (NUMBER_OF_STAGES == 1) begin | ||||||
|  |       always @ (posedge clk or negedge reset_n) | ||||||
|  |         pipe_out <= (!reset_n) ? 0 : pipe_in; | ||||||
|  |     end | ||||||
|  |     // Case for 2 or more pipeline stages | ||||||
|  |     else begin | ||||||
|  |       // Create the necessary regs | ||||||
|  |       reg [BIT_WIDTH*(NUMBER_OF_STAGES-1)-1:0] pipe_gen; | ||||||
|  |       // Create logic for the initial and final pipeline registers | ||||||
|  |       always @ (posedge clk or negedge reset_n) begin | ||||||
|  |         if (!reset_n) begin | ||||||
|  |           pipe_gen[BIT_WIDTH-1:0] <= 0; | ||||||
|  |           pipe_out                <= 0; | ||||||
|  |         end | ||||||
|  |         else begin | ||||||
|  |           pipe_gen[BIT_WIDTH-1:0] <= pipe_in; | ||||||
|  |           pipe_out                <= pipe_gen[BIT_WIDTH*(NUMBER_OF_STAGES-1)-1:BIT_WIDTH*(NUMBER_OF_STAGES-2)]; | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |       // Create the intermediate pipeline registers if there are 3 or | ||||||
|  |       // more pipeline stages | ||||||
|  |       for (i = 1; i < NUMBER_OF_STAGES-1; i = i + 1) begin : pipeline | ||||||
|  |         always @ (posedge clk or negedge reset_n) | ||||||
|  |           pipe_gen[BIT_WIDTH*(i+1)-1:BIT_WIDTH*i] <= (!reset_n) ? 0 : pipe_gen[BIT_WIDTH*i-1:BIT_WIDTH*(i-1)]; | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   endgenerate | ||||||
|  |    | ||||||
|  | endmodule | ||||||
							
								
								
									
										175
									
								
								samples/verilog/ps2_mouse.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										175
									
								
								samples/verilog/ps2_mouse.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,175 @@ | |||||||
|  | /* | ||||||
|  |  *  PS2 Mouse Interface | ||||||
|  |  *  Copyright (C) 2010  Donna Polehn <dpolehn@verizon.net> | ||||||
|  |  * | ||||||
|  |  *  This file is part of the Zet processor. This processor is free | ||||||
|  |  *  hardware; you can redistribute it and/or modify it under the terms of | ||||||
|  |  *  the GNU General Public License as published by the Free Software | ||||||
|  |  *  Foundation; either version 3, or (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *  Zet is distrubuted in the hope that it will be useful, but WITHOUT | ||||||
|  |  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||||||
|  |  *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | ||||||
|  |  *  License for more details. | ||||||
|  |  * | ||||||
|  |  *  You should have received a copy of the GNU General Public License | ||||||
|  |  *  along with Zet; see the file COPYING. If not, see | ||||||
|  |  *  <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | module ps2_mouse ( | ||||||
|  |     input clk,                // Clock Input | ||||||
|  |     input reset,              // Reset Input | ||||||
|  |     inout ps2_clk,            // PS2 Clock, Bidirectional | ||||||
|  |     inout ps2_dat,            // PS2 Data, Bidirectional | ||||||
|  |  | ||||||
|  |     input  [7:0] the_command,        // Command to send to mouse | ||||||
|  |     input        send_command,       // Signal to send | ||||||
|  |     output       command_was_sent,   // Signal command finished sending | ||||||
|  |     output       error_communication_timed_out, | ||||||
|  |  | ||||||
|  |     output [7:0] received_data,        // Received data | ||||||
|  |     output       received_data_en,     // If 1 - new data has been received | ||||||
|  |     output       start_receiving_data, | ||||||
|  |     output       wait_for_incoming_data | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   // Internal wires and registers Declarations | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   wire            ps2_clk_posedge;        // Internal Wires | ||||||
|  |   wire            ps2_clk_negedge; | ||||||
|  |  | ||||||
|  |   reg    [7:0]    idle_counter;            // Internal Registers | ||||||
|  |   reg             ps2_clk_reg; | ||||||
|  |   reg             ps2_data_reg; | ||||||
|  |   reg             last_ps2_clk; | ||||||
|  |  | ||||||
|  |   reg    [2:0]    ns_ps2_transceiver;        // State Machine Registers | ||||||
|  |   reg    [2:0]    s_ps2_transceiver; | ||||||
|  |  | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   // Constant Declarations | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   localparam  PS2_STATE_0_IDLE            = 3'h0,        // states | ||||||
|  |               PS2_STATE_1_DATA_IN         = 3'h1, | ||||||
|  |               PS2_STATE_2_COMMAND_OUT     = 3'h2, | ||||||
|  |               PS2_STATE_3_END_TRANSFER    = 3'h3, | ||||||
|  |               PS2_STATE_4_END_DELAYED     = 3'h4; | ||||||
|  |  | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   // Finite State Machine(s) | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   always @(posedge clk) begin | ||||||
|  |     if(reset == 1'b1) s_ps2_transceiver <= PS2_STATE_0_IDLE; | ||||||
|  |     else              s_ps2_transceiver <= ns_ps2_transceiver; | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   always @(*) begin | ||||||
|  |     ns_ps2_transceiver = PS2_STATE_0_IDLE;        // Defaults | ||||||
|  |  | ||||||
|  |     case (s_ps2_transceiver) | ||||||
|  |     PS2_STATE_0_IDLE: | ||||||
|  |         begin | ||||||
|  |             if((idle_counter == 8'hFF) && (send_command == 1'b1)) | ||||||
|  |                 ns_ps2_transceiver = PS2_STATE_2_COMMAND_OUT; | ||||||
|  |             else if ((ps2_data_reg == 1'b0) && (ps2_clk_posedge == 1'b1)) | ||||||
|  |                 ns_ps2_transceiver = PS2_STATE_1_DATA_IN; | ||||||
|  |             else ns_ps2_transceiver = PS2_STATE_0_IDLE; | ||||||
|  |         end | ||||||
|  |     PS2_STATE_1_DATA_IN: | ||||||
|  |         begin | ||||||
|  |             // if((received_data_en == 1'b1)  && (ps2_clk_posedge == 1'b1)) | ||||||
|  |             if((received_data_en == 1'b1))   ns_ps2_transceiver = PS2_STATE_0_IDLE; | ||||||
|  |             else                             ns_ps2_transceiver = PS2_STATE_1_DATA_IN; | ||||||
|  |         end | ||||||
|  |     PS2_STATE_2_COMMAND_OUT: | ||||||
|  |         begin | ||||||
|  |             if((command_was_sent == 1'b1) || (error_communication_timed_out == 1'b1)) | ||||||
|  |                 ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER; | ||||||
|  |             else ns_ps2_transceiver = PS2_STATE_2_COMMAND_OUT; | ||||||
|  |         end | ||||||
|  |     PS2_STATE_3_END_TRANSFER: | ||||||
|  |         begin | ||||||
|  |             if(send_command == 1'b0) ns_ps2_transceiver = PS2_STATE_0_IDLE; | ||||||
|  |             else if((ps2_data_reg == 1'b0) && (ps2_clk_posedge == 1'b1)) | ||||||
|  |                 ns_ps2_transceiver = PS2_STATE_4_END_DELAYED; | ||||||
|  |             else ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER; | ||||||
|  |         end | ||||||
|  |     PS2_STATE_4_END_DELAYED: | ||||||
|  |         begin | ||||||
|  |             if(received_data_en == 1'b1) begin | ||||||
|  |                 if(send_command == 1'b0) ns_ps2_transceiver = PS2_STATE_0_IDLE; | ||||||
|  |                 else                     ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER; | ||||||
|  |             end | ||||||
|  |             else ns_ps2_transceiver = PS2_STATE_4_END_DELAYED; | ||||||
|  |         end | ||||||
|  |  | ||||||
|  |     default: | ||||||
|  |             ns_ps2_transceiver = PS2_STATE_0_IDLE; | ||||||
|  |     endcase | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   // Sequential logic | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   always @(posedge clk) begin | ||||||
|  |     if(reset == 1'b1)     begin | ||||||
|  |         last_ps2_clk    <= 1'b1; | ||||||
|  |         ps2_clk_reg     <= 1'b1; | ||||||
|  |         ps2_data_reg    <= 1'b1; | ||||||
|  |     end | ||||||
|  |     else begin | ||||||
|  |         last_ps2_clk    <= ps2_clk_reg; | ||||||
|  |         ps2_clk_reg     <= ps2_clk; | ||||||
|  |         ps2_data_reg    <= ps2_dat; | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   always @(posedge clk) begin | ||||||
|  |     if(reset == 1'b1) idle_counter <= 6'h00; | ||||||
|  |     else if((s_ps2_transceiver == PS2_STATE_0_IDLE) && (idle_counter != 8'hFF)) | ||||||
|  |         idle_counter <= idle_counter + 6'h01; | ||||||
|  |     else if (s_ps2_transceiver != PS2_STATE_0_IDLE) | ||||||
|  |         idle_counter <= 6'h00; | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   // Combinational logic | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   assign ps2_clk_posedge = ((ps2_clk_reg == 1'b1) && (last_ps2_clk == 1'b0)) ? 1'b1 : 1'b0; | ||||||
|  |   assign ps2_clk_negedge = ((ps2_clk_reg == 1'b0) && (last_ps2_clk == 1'b1)) ? 1'b1 : 1'b0; | ||||||
|  |  | ||||||
|  |   assign start_receiving_data      = (s_ps2_transceiver == PS2_STATE_1_DATA_IN); | ||||||
|  |   assign wait_for_incoming_data    = (s_ps2_transceiver == PS2_STATE_3_END_TRANSFER); | ||||||
|  |  | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   // Internal Modules | ||||||
|  |   // -------------------------------------------------------------------- | ||||||
|  |   ps2_mouse_cmdout mouse_cmdout ( | ||||||
|  |     .clk                           (clk),            // Inputs | ||||||
|  |     .reset                         (reset), | ||||||
|  |     .the_command                   (the_command), | ||||||
|  |     .send_command                  (send_command), | ||||||
|  |     .ps2_clk_posedge               (ps2_clk_posedge), | ||||||
|  |     .ps2_clk_negedge               (ps2_clk_negedge), | ||||||
|  |     .ps2_clk                       (ps2_clk),        // Bidirectionals | ||||||
|  |     .ps2_dat                       (ps2_dat), | ||||||
|  |     .command_was_sent              (command_was_sent),    // Outputs | ||||||
|  |     .error_communication_timed_out (error_communication_timed_out) | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   ps2_mouse_datain mouse_datain ( | ||||||
|  |     .clk                    (clk),        // Inputs | ||||||
|  |     .reset                  (reset), | ||||||
|  |     .wait_for_incoming_data (wait_for_incoming_data), | ||||||
|  |     .start_receiving_data   (start_receiving_data), | ||||||
|  |     .ps2_clk_posedge        (ps2_clk_posedge), | ||||||
|  |     .ps2_clk_negedge        (ps2_clk_negedge), | ||||||
|  |     .ps2_data               (ps2_data_reg), | ||||||
|  |     .received_data          (received_data),   // Outputs | ||||||
|  |     .received_data_en       (received_data_en) | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  | endmodule | ||||||
|  |  | ||||||
							
								
								
									
										49
									
								
								samples/verilog/sign_extender.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										49
									
								
								samples/verilog/sign_extender.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Original Author: Schuyler Eldridge | ||||||
|  | // Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com) | ||||||
|  | // sign_extender.v | ||||||
|  | // Created: 5.16.2012 | ||||||
|  | // Modified: 5.16.2012 | ||||||
|  | // | ||||||
|  | // Generic sign extension module | ||||||
|  | // | ||||||
|  | // Copyright (C) 2012 Schuyler Eldridge, Boston University | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | `timescale 1ns/1ps | ||||||
|  | module sign_extender | ||||||
|  |   #( | ||||||
|  |     parameter | ||||||
|  |     INPUT_WIDTH = 8, | ||||||
|  |     OUTPUT_WIDTH = 16 | ||||||
|  |     ) | ||||||
|  |   ( | ||||||
|  |    input [INPUT_WIDTH-1:0] original, | ||||||
|  |    output reg [OUTPUT_WIDTH-1:0] sign_extended_original | ||||||
|  |    ); | ||||||
|  |  | ||||||
|  |   wire [OUTPUT_WIDTH-INPUT_WIDTH-1:0] sign_extend; | ||||||
|  |  | ||||||
|  |   generate | ||||||
|  |     genvar                           i; | ||||||
|  |     for (i = 0; i < OUTPUT_WIDTH-INPUT_WIDTH; i = i + 1) begin : gen_sign_extend | ||||||
|  |       assign sign_extend[i]  = (original[INPUT_WIDTH-1]) ? 1'b1 : 1'b0; | ||||||
|  |     end | ||||||
|  |   endgenerate | ||||||
|  |  | ||||||
|  |   always @ * begin | ||||||
|  |     sign_extended_original  = {sign_extend,original}; | ||||||
|  |   end | ||||||
|  |  | ||||||
|  | endmodule | ||||||
							
								
								
									
										154
									
								
								samples/verilog/sqrt_pipelined.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										154
									
								
								samples/verilog/sqrt_pipelined.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,154 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Original Author: Schuyler Eldridge | ||||||
|  | // Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com) | ||||||
|  | // sqrt_pipelined.v | ||||||
|  | // Created: 4.2.2012 | ||||||
|  | // Modified: 4.5.2012 | ||||||
|  | // | ||||||
|  | // Implements a fixed-point parameterized pipelined square root | ||||||
|  | // operation on an unsigned input of any bit length. The number of | ||||||
|  | // stages in the pipeline is equal to the number of output bits in the | ||||||
|  | // computation. This pipelien sustains a throughput of one computation | ||||||
|  | // per clock cycle. | ||||||
|  | //  | ||||||
|  | // Copyright (C) 2012 Schuyler Eldridge, Boston University | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | `timescale 1ns / 1ps | ||||||
|  | module sqrt_pipelined | ||||||
|  |   ( | ||||||
|  |    input                        clk,        // clock | ||||||
|  |    input                        reset_n,    // asynchronous reset | ||||||
|  |    input                        start,      // optional start signal | ||||||
|  |    input [INPUT_BITS-1:0]       radicand,   // unsigned radicand | ||||||
|  |    output reg                   data_valid, // optional data valid signal | ||||||
|  |    output reg [OUTPUT_BITS-1:0] root        // unsigned root  | ||||||
|  |    ); | ||||||
|  |  | ||||||
|  |   // WARNING!!! THESE PARAMETERS ARE INTENDED TO BE MODIFIED IN A TOP | ||||||
|  |   // LEVEL MODULE. LOCAL CHANGES HERE WILL, MOST LIKELY, BE | ||||||
|  |   // OVERWRITTEN! | ||||||
|  |   parameter | ||||||
|  |     INPUT_BITS   = 16; // number of input bits (any integer) | ||||||
|  |   localparam | ||||||
|  |     OUTPUT_BITS  = INPUT_BITS / 2 + INPUT_BITS % 2; // number of output bits | ||||||
|  |    | ||||||
|  |   reg [OUTPUT_BITS-1:0]         start_gen; // valid data propagation | ||||||
|  |   reg [OUTPUT_BITS*INPUT_BITS-1:0] root_gen; // root values | ||||||
|  |   reg [OUTPUT_BITS*INPUT_BITS-1:0] radicand_gen; // radicand values | ||||||
|  |   wire [OUTPUT_BITS*INPUT_BITS-1:0] mask_gen; // mask values | ||||||
|  |  | ||||||
|  |   // This is the first stage of the pipeline. | ||||||
|  |   always @ (posedge clk or negedge reset_n) begin | ||||||
|  |     if (!reset_n) begin | ||||||
|  |       start_gen[0]                 <= 0; | ||||||
|  |       radicand_gen[INPUT_BITS-1:0] <= 0; | ||||||
|  |       root_gen[INPUT_BITS-1:0]     <= 0; | ||||||
|  |     end | ||||||
|  |     else begin | ||||||
|  |       start_gen[0] <= start; | ||||||
|  |       if ( mask_gen[INPUT_BITS-1:0] <= radicand ) begin | ||||||
|  |         radicand_gen[INPUT_BITS-1:0] <= radicand - mask_gen[INPUT_BITS-1:0]; | ||||||
|  |         root_gen[INPUT_BITS-1:0] <= mask_gen[INPUT_BITS-1:0]; | ||||||
|  |       end | ||||||
|  |       else begin | ||||||
|  |         radicand_gen[INPUT_BITS-1:0] <= radicand; | ||||||
|  |         root_gen[INPUT_BITS-1:0] <= 0; | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   // Main generate loop to create the masks and pipeline stages. | ||||||
|  |   generate | ||||||
|  |     genvar i; | ||||||
|  |     // Generate all the mask values. These are built up in the | ||||||
|  |     // following fashion: | ||||||
|  |     // LAST MASK:  0x00...001  | ||||||
|  |     //             0x00...004  Increasing # OUTPUT_BITS | ||||||
|  |     //             0x00...010          | | ||||||
|  |     //             0x00...040          v | ||||||
|  |     //                 ... | ||||||
|  |     // FIRST MASK: 0x10...000  # masks == # OUTPUT_BITS | ||||||
|  |     //  | ||||||
|  |     // Note that the first mask used can either be of the 0x1... or | ||||||
|  |     // 0x4... variety. This is purely determined by the number of | ||||||
|  |     // computation stages. However, the last mask used will always be | ||||||
|  |     // 0x1 and the second to last mask used will always be 0x4. | ||||||
|  |     for (i = 0; i < OUTPUT_BITS; i = i + 1) begin: mask_4 | ||||||
|  |       if (i % 2) // i is odd, this is a 4 mask | ||||||
|  |         assign mask_gen[INPUT_BITS*(OUTPUT_BITS-i)-1:INPUT_BITS*(OUTPUT_BITS-i-1)]  = 4 << 4 * (i/2); | ||||||
|  |       else // i is even, this is a 1 mask | ||||||
|  |         assign mask_gen[INPUT_BITS*(OUTPUT_BITS-i)-1:INPUT_BITS*(OUTPUT_BITS-i-1)]  = 1 << 4 * (i/2); | ||||||
|  |     end | ||||||
|  |     // Generate all the pipeline stages to compute the square root of | ||||||
|  |     // the input radicand stream. The general approach is to compare | ||||||
|  |     // the current values of the root plus the mask to the | ||||||
|  |     // radicand. If root/mask sum is greater than the radicand, | ||||||
|  |     // subtract the mask and the root from the radicand and store the | ||||||
|  |     // radicand for the next stage. Additionally, the root is | ||||||
|  |     // increased by the value of the mask and stored for the next | ||||||
|  |     // stage. If this test fails, then the radicand and the root | ||||||
|  |     // retain their value through to the next stage. The one weird | ||||||
|  |     // thing is that the mask indices appear to be incremented by one | ||||||
|  |     // additional position. This is not the case, however, because the | ||||||
|  |     // first mask is used in the first stage (always block after the | ||||||
|  |     // generate statement). | ||||||
|  |     for (i = 0; i < OUTPUT_BITS - 1; i = i + 1) begin: pipeline | ||||||
|  |       always @ (posedge clk or negedge reset_n) begin : pipeline_stage | ||||||
|  |         if (!reset_n) begin | ||||||
|  |           start_gen[i+1]                                    <= 0; | ||||||
|  |           radicand_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= 0; | ||||||
|  |           root_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)]     <= 0; | ||||||
|  |         end | ||||||
|  |         else begin | ||||||
|  |           start_gen[i+1] <= start_gen[i]; | ||||||
|  |           if ((root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] +  | ||||||
|  |                mask_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)]) <= radicand_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i]) begin | ||||||
|  | 	    radicand_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= radicand_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] -  | ||||||
|  |                                                                  mask_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] -  | ||||||
|  |                                                                  root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i]; | ||||||
|  | 	    root_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= (root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] >> 1) +  | ||||||
|  |                                                              mask_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)]; | ||||||
|  |           end | ||||||
|  |           else begin | ||||||
|  | 	    radicand_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= radicand_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i]; | ||||||
|  | 	    root_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)]     <= root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] >> 1; | ||||||
|  |           end | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   endgenerate | ||||||
|  |  | ||||||
|  |   // This is the final stage which just implements a rounding | ||||||
|  |   // operation. This stage could be tacked on as a combinational logic | ||||||
|  |   // stage, but who cares about latency, anyway? This is NOT a true | ||||||
|  |   // rounding stage. In order to add convergent rounding, you need to | ||||||
|  |   // increase the input bit width by 2 (increase the number of | ||||||
|  |   // pipeline stages by 1) and implement rounding in the module that | ||||||
|  |   // instantiates this one.  | ||||||
|  |   always @ (posedge clk or negedge reset_n) begin | ||||||
|  |     if (!reset_n) begin | ||||||
|  |       data_valid <= 0; | ||||||
|  |       root       <= 0; | ||||||
|  |     end | ||||||
|  |     else begin | ||||||
|  |       data_valid <= start_gen[OUTPUT_BITS-1]; | ||||||
|  |       if (root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS] > root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS]) | ||||||
|  |         root <= root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS] + 1; | ||||||
|  |       else | ||||||
|  |         root  <= root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS]; | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  | endmodule | ||||||
							
								
								
									
										70
									
								
								samples/verilog/t_button_debounce.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										70
									
								
								samples/verilog/t_button_debounce.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Original Author: Schuyler Eldridge | ||||||
|  | // Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com) | ||||||
|  | // button_debounce.v | ||||||
|  | // Created:  4.5.2012 | ||||||
|  | // Modified: 4.5.2012 | ||||||
|  | // | ||||||
|  | // Testbench for button_debounce.v. | ||||||
|  | //  | ||||||
|  | // Copyright (C) 2012 Schuyler Eldridge, Boston University | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | `timescale 1ns / 1ps | ||||||
|  | module t_button_debounce(); | ||||||
|  |  | ||||||
|  |   parameter | ||||||
|  |     CLK_FREQUENCY  = 66000000, | ||||||
|  |     DEBOUNCE_HZ    = 2; | ||||||
|  |  | ||||||
|  |   reg clk, reset_n, button; | ||||||
|  |   wire debounce; | ||||||
|  |    | ||||||
|  |   button_debounce | ||||||
|  |     #( | ||||||
|  |       .CLK_FREQUENCY(CLK_FREQUENCY), | ||||||
|  |       .DEBOUNCE_HZ(DEBOUNCE_HZ) | ||||||
|  |       ) | ||||||
|  |   button_debounce | ||||||
|  |     ( | ||||||
|  |      .clk(clk), | ||||||
|  |      .reset_n(reset_n), | ||||||
|  |      .button(button), | ||||||
|  |      .debounce(debounce) | ||||||
|  |      ); | ||||||
|  |  | ||||||
|  |   initial begin | ||||||
|  |     clk          = 1'bx; reset_n = 1'bx; button = 1'bx; | ||||||
|  |     #10 reset_n  = 1; | ||||||
|  |     #10 reset_n  = 0; clk = 0; | ||||||
|  |     #10 reset_n  = 1; | ||||||
|  |     #10 button   = 0; | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   always | ||||||
|  |     #5 clk  = ~clk; | ||||||
|  |  | ||||||
|  |   always begin | ||||||
|  |     #100 button  = ~button; | ||||||
|  |     #0.1 button  = ~button; | ||||||
|  |     #0.1 button  = ~button; | ||||||
|  |     #0.1 button  = ~button; | ||||||
|  |     #0.1 button  = ~button; | ||||||
|  |     #0.1 button  = ~button; | ||||||
|  |     #0.1 button  = ~button; | ||||||
|  |     #0.1 button  = ~button; | ||||||
|  |     #0.1 button  = ~button; | ||||||
|  |   end | ||||||
|  |    | ||||||
|  | endmodule | ||||||
							
								
								
									
										75
									
								
								samples/verilog/t_div_pipelined.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										75
									
								
								samples/verilog/t_div_pipelined.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,75 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Original Author: Schuyler Eldridge | ||||||
|  | // Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com) | ||||||
|  | // div_pipelined.v | ||||||
|  | // Created: 4.3.2012 | ||||||
|  | // Modified: 4.5.2012 | ||||||
|  | // | ||||||
|  | // Testbench for div_pipelined.v | ||||||
|  | // | ||||||
|  | // Copyright (C) 2012 Schuyler Eldridge, Boston University | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | `timescale 1ns / 1ps | ||||||
|  | module t_div_pipelined(); | ||||||
|  |  | ||||||
|  |   reg clk, start, reset_n; | ||||||
|  |   reg [7:0] dividend, divisor; | ||||||
|  |   wire      data_valid, div_by_zero; | ||||||
|  |   wire [7:0] quotient, quotient_correct; | ||||||
|  |  | ||||||
|  |   parameter | ||||||
|  |     BITS  = 8; | ||||||
|  |  | ||||||
|  |   div_pipelined | ||||||
|  |     #( | ||||||
|  |       .BITS(BITS) | ||||||
|  |       ) | ||||||
|  |   div_pipelined | ||||||
|  |     ( | ||||||
|  |      .clk(clk), | ||||||
|  |      .reset_n(reset_n), | ||||||
|  |      .dividend(dividend), | ||||||
|  |      .divisor(divisor), | ||||||
|  |      .quotient(quotient), | ||||||
|  |      .div_by_zero(div_by_zero), | ||||||
|  |      //     .quotient_correct(quotient_correct), | ||||||
|  |      .start(start), | ||||||
|  |      .data_valid(data_valid) | ||||||
|  |      ); | ||||||
|  |  | ||||||
|  |   initial begin | ||||||
|  |     #10 reset_n  = 0; | ||||||
|  |     #50 reset_n  = 1; | ||||||
|  |     #1 | ||||||
|  |     clk          = 0; | ||||||
|  |     dividend     = -1; | ||||||
|  |     divisor      = 127; | ||||||
|  |     #1000 $finish; | ||||||
|  |   end | ||||||
|  |  | ||||||
|  | //  always | ||||||
|  | //    #20 dividend  = dividend + 1; | ||||||
|  |  | ||||||
|  |   always begin | ||||||
|  |     #10 divisor  = divisor - 1; start = 1; | ||||||
|  |     #10 start    = 0; | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   always | ||||||
|  |     #5 clk  = ~clk; | ||||||
|  |  | ||||||
|  |    | ||||||
|  | endmodule | ||||||
|  |    | ||||||
							
								
								
									
										77
									
								
								samples/verilog/t_sqrt_pipelined.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										77
									
								
								samples/verilog/t_sqrt_pipelined.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Original Author: Schuyler Eldridge | ||||||
|  | // Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com) | ||||||
|  | // t_sqrt_pipelined.v | ||||||
|  | // Created: 4.2.2012 | ||||||
|  | // Modified: 4.5.2012 | ||||||
|  | // | ||||||
|  | // Testbench for generic sqrt operation | ||||||
|  | //  | ||||||
|  | // Copyright (C) 2012 Schuyler Eldridge, Boston University | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | `timescale 1ns / 1ps | ||||||
|  | module t_sqrt_pipelined(); | ||||||
|  |  | ||||||
|  |   parameter  | ||||||
|  |     INPUT_BITS  = 4; | ||||||
|  |   localparam | ||||||
|  |     OUTPUT_BITS  = INPUT_BITS / 2 + INPUT_BITS % 2; | ||||||
|  |    | ||||||
|  |   reg [INPUT_BITS-1:0] radicand; | ||||||
|  |   reg                  clk, start, reset_n; | ||||||
|  |  | ||||||
|  |   wire [OUTPUT_BITS-1:0] root; | ||||||
|  |   wire                   data_valid; | ||||||
|  | //  wire [7:0] root_good; | ||||||
|  |  | ||||||
|  |   sqrt_pipelined  | ||||||
|  |     #( | ||||||
|  |       .INPUT_BITS(INPUT_BITS) | ||||||
|  |       ) | ||||||
|  |     sqrt_pipelined  | ||||||
|  |       ( | ||||||
|  |        .clk(clk), | ||||||
|  |        .reset_n(reset_n), | ||||||
|  |        .start(start), | ||||||
|  |        .radicand(radicand),  | ||||||
|  |        .data_valid(data_valid), | ||||||
|  |        .root(root) | ||||||
|  |        ); | ||||||
|  |  | ||||||
|  |   initial begin | ||||||
|  |     radicand     = 16'bx; clk = 1'bx; start = 1'bx; reset_n = 1'bx;; | ||||||
|  |     #10 reset_n  = 0; clk = 0; | ||||||
|  |     #50 reset_n  = 1; radicand = 0; | ||||||
|  | //    #40 radicand  = 81; start = 1; | ||||||
|  | //    #10 radicand  = 16'bx; start = 0; | ||||||
|  |     #10000 $finish; | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   always | ||||||
|  |     #5 clk = ~clk; | ||||||
|  |  | ||||||
|  |   always begin | ||||||
|  |     #10 radicand  = radicand + 1; start = 1; | ||||||
|  |     #10 start     = 0; | ||||||
|  |   end | ||||||
|  |    | ||||||
|  |  | ||||||
|  | //  always begin | ||||||
|  | //    #80 start  = 1; | ||||||
|  | //    #10 start  = 0; | ||||||
|  | //  end | ||||||
|  |  | ||||||
|  | endmodule | ||||||
|  |  | ||||||
							
								
								
									
										313
									
								
								samples/verilog/vga.v
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										313
									
								
								samples/verilog/vga.v
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,313 @@ | |||||||
|  | /* | ||||||
|  |  *  VGA top level file | ||||||
|  |  *  Copyright (C) 2010  Zeus Gomez Marmolejo <zeus@aluzina.org> | ||||||
|  |  * | ||||||
|  |  *  This file is part of the Zet processor. This processor is free | ||||||
|  |  *  hardware; you can redistribute it and/or modify it under the terms of | ||||||
|  |  *  the GNU General Public License as published by the Free Software | ||||||
|  |  *  Foundation; either version 3, or (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *  Zet is distrubuted in the hope that it will be useful, but WITHOUT | ||||||
|  |  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||||||
|  |  *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | ||||||
|  |  *  License for more details. | ||||||
|  |  * | ||||||
|  |  *  You should have received a copy of the GNU General Public License | ||||||
|  |  *  along with Zet; see the file COPYING. If not, see | ||||||
|  |  *  <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | module vga ( | ||||||
|  |     // Wishbone signals | ||||||
|  |     input         wb_clk_i,     // 25 Mhz VDU clock | ||||||
|  |     input         wb_rst_i, | ||||||
|  |     input  [15:0] wb_dat_i, | ||||||
|  |     output [15:0] wb_dat_o, | ||||||
|  |     input  [16:1] wb_adr_i, | ||||||
|  |     input         wb_we_i, | ||||||
|  |     input         wb_tga_i, | ||||||
|  |     input  [ 1:0] wb_sel_i, | ||||||
|  |     input         wb_stb_i, | ||||||
|  |     input         wb_cyc_i, | ||||||
|  |     output        wb_ack_o, | ||||||
|  |  | ||||||
|  |     // VGA pad signals | ||||||
|  |     output [ 3:0] vga_red_o, | ||||||
|  |     output [ 3:0] vga_green_o, | ||||||
|  |     output [ 3:0] vga_blue_o, | ||||||
|  |     output        horiz_sync, | ||||||
|  |     output        vert_sync, | ||||||
|  |  | ||||||
|  |     // CSR SRAM master interface | ||||||
|  |     output [17:1] csrm_adr_o, | ||||||
|  |     output [ 1:0] csrm_sel_o, | ||||||
|  |     output        csrm_we_o, | ||||||
|  |     output [15:0] csrm_dat_o, | ||||||
|  |     input  [15:0] csrm_dat_i | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   // Registers and nets | ||||||
|  |   // | ||||||
|  |   // csr address | ||||||
|  |   reg  [17:1] csr_adr_i; | ||||||
|  |   reg         csr_stb_i; | ||||||
|  |  | ||||||
|  |   // Config wires | ||||||
|  |   wire [15:0] conf_wb_dat_o; | ||||||
|  |   wire        conf_wb_ack_o; | ||||||
|  |  | ||||||
|  |   // Mem wires | ||||||
|  |   wire [15:0] mem_wb_dat_o; | ||||||
|  |   wire        mem_wb_ack_o; | ||||||
|  |  | ||||||
|  |   // LCD wires | ||||||
|  |   wire [17:1] csr_adr_o; | ||||||
|  |   wire [15:0] csr_dat_i; | ||||||
|  |   wire        csr_stb_o; | ||||||
|  |   wire        v_retrace; | ||||||
|  |   wire        vh_retrace; | ||||||
|  |   wire        w_vert_sync; | ||||||
|  |  | ||||||
|  |   // VGA configuration registers | ||||||
|  |   wire        shift_reg1; | ||||||
|  |   wire        graphics_alpha; | ||||||
|  |   wire        memory_mapping1; | ||||||
|  |   wire [ 1:0] write_mode; | ||||||
|  |   wire [ 1:0] raster_op; | ||||||
|  |   wire        read_mode; | ||||||
|  |   wire [ 7:0] bitmask; | ||||||
|  |   wire [ 3:0] set_reset; | ||||||
|  |   wire [ 3:0] enable_set_reset; | ||||||
|  |   wire [ 3:0] map_mask; | ||||||
|  |   wire        x_dotclockdiv2; | ||||||
|  |   wire        chain_four; | ||||||
|  |   wire [ 1:0] read_map_select; | ||||||
|  |   wire [ 3:0] color_compare; | ||||||
|  |   wire [ 3:0] color_dont_care; | ||||||
|  |  | ||||||
|  |   // Wishbone master to SRAM | ||||||
|  |   wire [17:1] wbm_adr_o; | ||||||
|  |   wire [ 1:0] wbm_sel_o; | ||||||
|  |   wire        wbm_we_o; | ||||||
|  |   wire [15:0] wbm_dat_o; | ||||||
|  |   wire [15:0] wbm_dat_i; | ||||||
|  |   wire        wbm_stb_o; | ||||||
|  |   wire        wbm_ack_i; | ||||||
|  |  | ||||||
|  |   wire        stb; | ||||||
|  |  | ||||||
|  |   // CRT wires | ||||||
|  |   wire [ 5:0] cur_start; | ||||||
|  |   wire [ 5:0] cur_end; | ||||||
|  |   wire [15:0] start_addr; | ||||||
|  |   wire [ 4:0] vcursor; | ||||||
|  |   wire [ 6:0] hcursor; | ||||||
|  |   wire [ 6:0] horiz_total; | ||||||
|  |   wire [ 6:0] end_horiz; | ||||||
|  |   wire [ 6:0] st_hor_retr; | ||||||
|  |   wire [ 4:0] end_hor_retr; | ||||||
|  |   wire [ 9:0] vert_total; | ||||||
|  |   wire [ 9:0] end_vert; | ||||||
|  |   wire [ 9:0] st_ver_retr; | ||||||
|  |   wire [ 3:0] end_ver_retr; | ||||||
|  |  | ||||||
|  |   // attribute_ctrl wires | ||||||
|  |   wire [3:0] pal_addr; | ||||||
|  |   wire       pal_we; | ||||||
|  |   wire [7:0] pal_read; | ||||||
|  |   wire [7:0] pal_write; | ||||||
|  |  | ||||||
|  |   // dac_regs wires | ||||||
|  |   wire       dac_we; | ||||||
|  |   wire [1:0] dac_read_data_cycle; | ||||||
|  |   wire [7:0] dac_read_data_register; | ||||||
|  |   wire [3:0] dac_read_data; | ||||||
|  |   wire [1:0] dac_write_data_cycle; | ||||||
|  |   wire [7:0] dac_write_data_register; | ||||||
|  |   wire [3:0] dac_write_data; | ||||||
|  |  | ||||||
|  |   // Module instances | ||||||
|  |   // | ||||||
|  |   vga_config_iface config_iface ( | ||||||
|  |     .wb_clk_i (wb_clk_i), | ||||||
|  |     .wb_rst_i (wb_rst_i), | ||||||
|  |     .wb_dat_i (wb_dat_i), | ||||||
|  |     .wb_dat_o (conf_wb_dat_o), | ||||||
|  |     .wb_adr_i (wb_adr_i[4:1]), | ||||||
|  |     .wb_we_i  (wb_we_i), | ||||||
|  |     .wb_sel_i (wb_sel_i), | ||||||
|  |     .wb_stb_i (stb & wb_tga_i), | ||||||
|  |     .wb_ack_o (conf_wb_ack_o), | ||||||
|  |  | ||||||
|  |     .shift_reg1       (shift_reg1), | ||||||
|  |     .graphics_alpha   (graphics_alpha), | ||||||
|  |     .memory_mapping1  (memory_mapping1), | ||||||
|  |     .write_mode       (write_mode), | ||||||
|  |     .raster_op        (raster_op), | ||||||
|  |     .read_mode        (read_mode), | ||||||
|  |     .bitmask          (bitmask), | ||||||
|  |     .set_reset        (set_reset), | ||||||
|  |     .enable_set_reset (enable_set_reset), | ||||||
|  |     .map_mask         (map_mask), | ||||||
|  |     .x_dotclockdiv2   (x_dotclockdiv2), | ||||||
|  |     .chain_four       (chain_four), | ||||||
|  |     .read_map_select  (read_map_select), | ||||||
|  |     .color_compare    (color_compare), | ||||||
|  |     .color_dont_care  (color_dont_care), | ||||||
|  |  | ||||||
|  |     .pal_addr  (pal_addr), | ||||||
|  |     .pal_we    (pal_we), | ||||||
|  |     .pal_read  (pal_read), | ||||||
|  |     .pal_write (pal_write), | ||||||
|  |  | ||||||
|  |     .dac_we                  (dac_we), | ||||||
|  |     .dac_read_data_cycle     (dac_read_data_cycle), | ||||||
|  |     .dac_read_data_register  (dac_read_data_register), | ||||||
|  |     .dac_read_data           (dac_read_data), | ||||||
|  |     .dac_write_data_cycle    (dac_write_data_cycle), | ||||||
|  |     .dac_write_data_register (dac_write_data_register), | ||||||
|  |     .dac_write_data          (dac_write_data), | ||||||
|  |  | ||||||
|  |     .cur_start  (cur_start), | ||||||
|  |     .cur_end    (cur_end), | ||||||
|  |     .start_addr (start_addr), | ||||||
|  |     .vcursor    (vcursor), | ||||||
|  |     .hcursor    (hcursor), | ||||||
|  |  | ||||||
|  |     .horiz_total  (horiz_total), | ||||||
|  |     .end_horiz    (end_horiz), | ||||||
|  |     .st_hor_retr  (st_hor_retr), | ||||||
|  |     .end_hor_retr (end_hor_retr), | ||||||
|  |     .vert_total   (vert_total), | ||||||
|  |     .end_vert     (end_vert), | ||||||
|  |     .st_ver_retr  (st_ver_retr), | ||||||
|  |     .end_ver_retr (end_ver_retr), | ||||||
|  |  | ||||||
|  |     .v_retrace  (v_retrace), | ||||||
|  |     .vh_retrace (vh_retrace) | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   vga_lcd lcd ( | ||||||
|  |     .clk (wb_clk_i), | ||||||
|  |     .rst (wb_rst_i), | ||||||
|  |  | ||||||
|  |     .shift_reg1     (shift_reg1), | ||||||
|  |     .graphics_alpha (graphics_alpha), | ||||||
|  |  | ||||||
|  |     .pal_addr  (pal_addr), | ||||||
|  |     .pal_we    (pal_we), | ||||||
|  |     .pal_read  (pal_read), | ||||||
|  |     .pal_write (pal_write), | ||||||
|  |  | ||||||
|  |     .dac_we                  (dac_we), | ||||||
|  |     .dac_read_data_cycle     (dac_read_data_cycle), | ||||||
|  |     .dac_read_data_register  (dac_read_data_register), | ||||||
|  |     .dac_read_data           (dac_read_data), | ||||||
|  |     .dac_write_data_cycle    (dac_write_data_cycle), | ||||||
|  |     .dac_write_data_register (dac_write_data_register), | ||||||
|  |     .dac_write_data          (dac_write_data), | ||||||
|  |  | ||||||
|  |     .csr_adr_o (csr_adr_o), | ||||||
|  |     .csr_dat_i (csr_dat_i), | ||||||
|  |     .csr_stb_o (csr_stb_o), | ||||||
|  |  | ||||||
|  |     .vga_red_o   (vga_red_o), | ||||||
|  |     .vga_green_o (vga_green_o), | ||||||
|  |     .vga_blue_o  (vga_blue_o), | ||||||
|  |     .horiz_sync  (horiz_sync), | ||||||
|  |     .vert_sync   (w_vert_sync), | ||||||
|  |  | ||||||
|  |     .cur_start  (cur_start), | ||||||
|  |     .cur_end    (cur_end), | ||||||
|  |     .vcursor    (vcursor), | ||||||
|  |     .hcursor    (hcursor), | ||||||
|  |  | ||||||
|  |     .horiz_total  (horiz_total), | ||||||
|  |     .end_horiz    (end_horiz), | ||||||
|  |     .st_hor_retr  (st_hor_retr), | ||||||
|  |     .end_hor_retr (end_hor_retr), | ||||||
|  |     .vert_total   (vert_total), | ||||||
|  |     .end_vert     (end_vert), | ||||||
|  |     .st_ver_retr  (st_ver_retr), | ||||||
|  |     .end_ver_retr (end_ver_retr), | ||||||
|  |  | ||||||
|  |     .x_dotclockdiv2 (x_dotclockdiv2), | ||||||
|  |  | ||||||
|  |     .v_retrace  (v_retrace), | ||||||
|  |     .vh_retrace (vh_retrace) | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   vga_cpu_mem_iface cpu_mem_iface ( | ||||||
|  |     .wb_clk_i (wb_clk_i), | ||||||
|  |     .wb_rst_i (wb_rst_i), | ||||||
|  |  | ||||||
|  |     .wbs_adr_i (wb_adr_i), | ||||||
|  |     .wbs_sel_i (wb_sel_i), | ||||||
|  |     .wbs_we_i  (wb_we_i), | ||||||
|  |     .wbs_dat_i (wb_dat_i), | ||||||
|  |     .wbs_dat_o (mem_wb_dat_o), | ||||||
|  |     .wbs_stb_i (stb & !wb_tga_i), | ||||||
|  |     .wbs_ack_o (mem_wb_ack_o), | ||||||
|  |  | ||||||
|  |     .wbm_adr_o (wbm_adr_o), | ||||||
|  |     .wbm_sel_o (wbm_sel_o), | ||||||
|  |     .wbm_we_o  (wbm_we_o), | ||||||
|  |     .wbm_dat_o (wbm_dat_o), | ||||||
|  |     .wbm_dat_i (wbm_dat_i), | ||||||
|  |     .wbm_stb_o (wbm_stb_o), | ||||||
|  |     .wbm_ack_i (wbm_ack_i), | ||||||
|  |  | ||||||
|  |     .chain_four       (chain_four), | ||||||
|  |     .memory_mapping1  (memory_mapping1), | ||||||
|  |     .write_mode       (write_mode), | ||||||
|  |     .raster_op        (raster_op), | ||||||
|  |     .read_mode        (read_mode), | ||||||
|  |     .bitmask          (bitmask), | ||||||
|  |     .set_reset        (set_reset), | ||||||
|  |     .enable_set_reset (enable_set_reset), | ||||||
|  |     .map_mask         (map_mask), | ||||||
|  |     .read_map_select  (read_map_select), | ||||||
|  |     .color_compare    (color_compare), | ||||||
|  |     .color_dont_care  (color_dont_care) | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   vga_mem_arbitrer mem_arbitrer ( | ||||||
|  |     .clk_i (wb_clk_i), | ||||||
|  |     .rst_i (wb_rst_i), | ||||||
|  |  | ||||||
|  |     .wb_adr_i (wbm_adr_o), | ||||||
|  |     .wb_sel_i (wbm_sel_o), | ||||||
|  |     .wb_we_i  (wbm_we_o), | ||||||
|  |     .wb_dat_i (wbm_dat_o), | ||||||
|  |     .wb_dat_o (wbm_dat_i), | ||||||
|  |     .wb_stb_i (wbm_stb_o), | ||||||
|  |     .wb_ack_o (wbm_ack_i), | ||||||
|  |  | ||||||
|  |     .csr_adr_i (csr_adr_i), | ||||||
|  |     .csr_dat_o (csr_dat_i), | ||||||
|  |     .csr_stb_i (csr_stb_i), | ||||||
|  |  | ||||||
|  |     .csrm_adr_o (csrm_adr_o), | ||||||
|  |     .csrm_sel_o (csrm_sel_o), | ||||||
|  |     .csrm_we_o  (csrm_we_o), | ||||||
|  |     .csrm_dat_o (csrm_dat_o), | ||||||
|  |     .csrm_dat_i (csrm_dat_i) | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   // Continous assignments | ||||||
|  |   assign wb_dat_o  = wb_tga_i ? conf_wb_dat_o : mem_wb_dat_o; | ||||||
|  |   assign wb_ack_o  = wb_tga_i ? conf_wb_ack_o : mem_wb_ack_o; | ||||||
|  |   assign stb       = wb_stb_i & wb_cyc_i; | ||||||
|  |   assign vert_sync = ~graphics_alpha ^ w_vert_sync; | ||||||
|  |  | ||||||
|  |   // Behaviour | ||||||
|  |   // csr_adr_i | ||||||
|  |   always @(posedge wb_clk_i) | ||||||
|  |     csr_adr_i <= wb_rst_i ? 17'h0 : csr_adr_o + start_addr[15:1]; | ||||||
|  |  | ||||||
|  |   // csr_stb_i | ||||||
|  |   always @(posedge wb_clk_i) | ||||||
|  |     csr_stb_i <= wb_rst_i ? 1'b0 : csr_stb_o; | ||||||
|  |  | ||||||
|  | endmodule | ||||||
		Reference in New Issue
	
	Block a user