mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			876 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Coq
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			876 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Coq
		
	
	
		
			Executable File
		
	
	
	
	
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.
 | 
						|
 |