-
Notifications
You must be signed in to change notification settings - Fork 0
Examples of usages of second order theorems (induction invariants and friends)
Mayank Keoliya edited this page Jun 10, 2022
·
26 revisions
- Induction principles
- Loop invariants/VST etc.
- Comparison functions?
- Logical Relations
Note: Does not fully reduce; may need dataflow analysis.
Require Import Arith.
Lemma add_comm :
forall a b,
a + b = b + a.
Proof.
intros a.
pose (fun b => a + b = b + a) as I.
(* evar (HI: I 0). *)
(* evar (HInd: (forall n : nat, I n -> I (S n))). *)
(* print_reduced (nat_ind I ?HI ?HInd 3). *)
apply (nat_ind (fun b : nat => a + b = b + a)).
rewrite <- plus_n_O.
rewrite plus_O_n.
reflexivity.
intros n Hn.
rewrite <- plus_n_Sm.
rewrite plus_Sn_m.
rewrite Nat.add_comm.
reflexivity.
Qed.
Variables A : Set.
Variables P Q : A -> Prop.
Lemma ex_3 : (exists x : A, P x \/ Q x) -> ex P \/ ex Q.
intros.
apply ex_ind with (P0 := ex P \/ ex Q) in H.
apply H.
intros.
apply or_ind with (P := (ex P \/ ex Q)) in H0.
apply H0.
intro.
apply or_introl.
apply ex_intro with (x := x).
apply H1.
intro.
apply or_intror.
apply ex_intro with (x := x).
apply H1.
Qed.
Set Implicit Arguments.
Set Strict Implicit.
Section PairWF.
Variables T U : Type.
Variable RT : T -> T -> Prop.
Variable RU : U -> U -> Prop.
Inductive R_pair : T * U -> T * U -> Prop :=
| L : forall l l' r r',
RT l l' -> R_pair (l,r) (l',r')
| R : forall l r r',
RU r r' -> R_pair (l,r) (l,r').
Hypothesis wf_RT : well_founded RT.
Hypothesis wf_RU : well_founded RU.
Theorem wf_R_pair : well_founded R_pair.
Proof.
red. intro x.
destruct x. generalize dependent u.
apply (well_founded_ind wf_RT (fun t => forall u : U, Acc R_pair (t, u))) .
do 2 intro.
apply (well_founded_ind wf_RU (fun u => Acc R_pair (x,u))). intros.
constructor. destruct y.
remember (t0,u). remember (x,x0). inversion 1; subst;
inversion H4; inversion H3; clear H4 H3; subst; eauto.
Defined.
End PairWF.
Require Export Arith.
Require Export ArithRing.
Require Export Wf_nat.
Section div_it_assumed.
Parameter div_it : forall (n m : nat), 0 < m -> nat * nat.
Hypothesis
div_it_fix_eqn :
forall (n m : nat) (h : 0 < m),
div_it n m h = match le_gt_dec m n with
left H => let (q, r) := div_it (n - m) m h in (S q, r)
| right H => (0, n)
end.
Theorem div_it_correct1:
forall (m n : nat) (h : 0 < n),
m = fst (div_it m n h) * n + snd (div_it m n h).
Proof.
intros m.
Check (well_founded_ind lt_wf).
Check (fun m => forall (n : nat) (h : 0 < n), m = fst (div_it m n h) * n + snd (div_it m n h)).
Check (well_founded_ind lt_wf (fun m => forall (n : nat) (h : 0 < n), m = fst (div_it m n h) * n + snd (div_it m n h))).
apply ((well_founded_ind lt_wf (fun m => forall (n : nat) (h : 0 < n), m = fst (div_it m n h) * n + snd (div_it m n h)))).
intros m' Hrec.
intros n h; rewrite div_it_fix_eqn.
case (le_gt_dec n m'); intros H; trivial.
pattern m' at 1; rewrite (le_plus_minus n m'); auto.
pattern (m' - n) at 1; rewrite Hrec with (m' - n) n h; auto with arith.
case (div_it (m' - n) n h); simpl; auto with arith.
Qed.
Require Import Program Div2 Omega.
Require Import Arith Arith.Even Arith.Div2 NPeano.
Require Import Coq.Program.Wf Init.Wf.
Require Import Coq.Arith.Max.
Require Import Coq.Arith.Mult.
Fixpoint sum (i j : nat) (f : nat -> nat) : nat :=
match (Nat.compare i j) with
| Lt => match j with
| 0 => 0
| S j' => sum i j' f + f j
end
| Eq => f i
| Gt => 0
end.
Lemma sum_adds_0 :
forall j f, sum 0 j f = f 0 + sum 1 j f.
Proof.
intros.
apply (well_founded_ind
lt_wf
(fun j => sum 0 j f = f 0 + sum 1 j f)).
intros.
destruct x. simpl. omega.
simpl.
destruct x. simpl. auto.
rewrite plus_assoc. rewrite <- H. auto. auto.
Qed.
Theorem n_le_m__Sn_le_Sm : forall n m,
n <= m -> S n <= S m.
Proof.
intros.
induction H using le_ind.
- apply le_n.
- apply le_S.
apply IHle.
Restart.
intros.
Check le_ind n (fun m => S n <= S m).
apply (le_ind n (fun m => S n <= S m)).
- apply le_n.
- intros.
apply le_S.
apply H1.
- apply H.
Qed.
Lemma map_compose {A B C : Type} (f : A -> B) (g : B -> C) (xs : list A) :
map (fun x => g (f x)) xs = map g (map f xs).
Proof.
revert xs.
Check list_ind (fun xs => map (fun x : A => g (f x)) xs = map g (map f xs)).
apply (list_ind (fun xs => map (fun x : A => g (f x)) xs = map g (map f xs))).
- reflexivity.
- intros x xs IH. rewrite !map_cons, IH. reflexivity.
Qed.
Lemma minus_le_lem2c : forall a b : nat, a - S b <= a - b.
intros. pattern a, b in |- *. apply nat_double_ind. auto with arith.
intro. elim minus_n_O. rewrite minus_n_SO. simpl in |- *. auto with arith.
intros. simpl in |- *. exact H.
Qed.
From Coq Require Export ZArith.
From Coq Require Import Lia.
Require Export Coq.Arith.Even.
Require Export Coq.Arith.Max.
Require Export Coq.Arith.Min.
Require Import Coq.Logic.Eqdep_dec.
Require Import Coq.Setoids.Setoid.
(* begin hide *)
Coercion Zpos : positive >-> Z.
Coercion Z_of_nat : nat >-> Z.
(* end hide *)
Definition caseZ_diff {A : Type} (z : Z) (f : nat -> nat -> A) :=
match z with
| Z0 => f 0 0
| Zpos m => f (nat_of_P m) 0
| Zneg m => f 0 (nat_of_P m)
end.
Lemma caseZ_diff_Pos : forall (A : Type) (f : nat -> nat -> A) (n : nat),
caseZ_diff n f = f n 0.
Proof.
intros A f n.
elim n.
reflexivity.
intros n0 H.
simpl in |- *.
rewrite nat_of_P_o_P_of_succ_nat_eq_succ.
reflexivity.
Qed.
Lemma caseZ_diff_Neg : forall (A : Type) (f : nat -> nat -> A) (n : nat),
caseZ_diff (- n) f = f 0 n.
Proof.
intros A f n.
elim n.
reflexivity.
intros n0 H.
simpl in |- *.
rewrite nat_of_P_o_P_of_succ_nat_eq_succ.
reflexivity.
Qed.
Lemma proper_caseZ_diff : forall (A : Type) (f : nat -> nat -> A),
(forall m n p q : nat, m + q = n + p -> f m n = f p q) ->
forall m n : nat, caseZ_diff (m - n) f = f m n.
Proof.
intros A F H m n.
pattern m, n in |- *.
Check nat_double_ind.
apply (nat_double_ind ((fun n0 n1 : nat => caseZ_diff (n0 - n1) F = F n0 n1))).
intro n0.
replace (0%nat - n0)%Z with (- n0)%Z.
rewrite caseZ_diff_Neg.
reflexivity.
simpl in |- *.
reflexivity.
intro n0.
replace (S n0 - 0%nat)%Z with (Z_of_nat (S n0)).
rewrite caseZ_diff_Pos.
reflexivity.
simpl in |- *.
reflexivity.
intros n0 m0 H0.
rewrite (H (S n0) (S m0) n0 m0).
rewrite <- H0.
replace (S n0 - S m0)%Z with (n0 - m0)%Z.
reflexivity.
repeat rewrite Znat.inj_S.
auto with zarith.
auto with zarith.
Qed.
Theorem le_or_lt : forall n m, n <= m \/ m < n.
Proof.
intros n m; pattern n, m; apply nat_double_ind; auto with arith.
induction 1; auto with arith.
Qed.
Lemma mult_minus_distr_r : forall n m p, (n - m) * p = n * p - m * p.
Proof.
intros.
Check nat_double_ind.
apply (nat_double_ind (fun n m => (n - m) * p = n * p - m * p)); simpl; auto with arith.
intros. rewrite <- minus_plus_simpl_l_reverse; auto with arith.
Qed.
Require Import List.
Require Import sflib. (* Software Foundations Lib *)
Notation "[ x ]" := (cons x nil) : list_scope.
Definition lastn {A} (n: nat) (l: list A) :=
List.rev (List.firstn n (List.rev l)).
Lemma lastn_snoc A n (l:list A) x:
lastn (S n) (l ++ [x]) = (lastn n l) ++ [x].
Proof.
revert n. induction l using List.rev_ind; ss.
unfold lastn. s. rewrite List.rev_app_distr. ss.
Qed.
Inductive lt_nat2 : (nat * nat) -> (nat * nat) -> Prop :=
| fst_lt2 : forall a b c d, a < b -> lt_nat2 (a , c) (b, d)
| snd_lt2 : forall a b c, b < c -> lt_nat2 (a, b) (a, c).
Notation "a <2 b" := (lt_nat2 a b) (at level 90) : nat_scope.
Lemma wf_lt_nat2 : well_founded lt_nat2.
Proof.
intros [n m].
revert m.
apply (lt_wf_ind n) ; clear n.
intros n Hn m.
apply (lt_wf_ind m); clear m.
intros m Hm.
apply Acc_intro.
intros [n' m'] Hlt2.
inversion Hlt2; subst.
- apply Hn.
apply H0.
- apply Hm.
apply H0.
Qed.
Lemma lt_nat2_wf_rect :
forall n (P:(nat*nat) -> Type), (forall n, (forall m, m <2 n -> P m) -> P n) -> P n.
Proof.
intros n P Hw.
apply well_founded_induction_type with lt_nat2.
- apply wf_lt_nat2.
- assumption.
Qed.
Lemma Z_succ_pred_induction y (P : Z → Prop) :
P y →
(∀ x, y ≤ x → P x → P (Z.succ x)) →
(∀ x, x ≤ y → P x → P (Z.pred x)) →
(∀ x, P x).
Proof. intros H0 HS HP. by apply (Z.order_induction' _ _ y). Qed.
Require Import Setoid.
Require Export LibListSorted.
Require Export LibList.
Require Export LibFset.
Require Export LibRelation.
Notation " Ctx *=* Ctx'" := (permut Ctx Ctx') (at level 70) : permut_scope.
Variable A:Type.
Inductive Permutation : list A -> list A -> Prop :=
| perm_nil: Permutation nil nil
| 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.
Theorem permut_equiv:
forall l1 l2,
l1 *=* l2 <->
Permutation l1 l2.
split; intro.
generalize dependent l2;
generalize dependent l1;
apply rtclosure_ind; intros; auto;
transitivity y; auto; inversion H; subst; apply Permutation_swap_middle.
induction H; permut_simpl; auto; transitivity l'; auto.
Qed.
See this file with higher-order function
Coercion Z.of_nat : nat >-> Z.
Local Open Scope Z_scope.
Notation "(≤)" := Z.le (only parsing) : Z_scope.
Lemma Z_succ_pred_induction y (P : Z -> Prop) :
P y ->
(forall x, y <= x -> P x -> P (Z.succ x)) ->
(forall x, x <= y -> P x -> P (Z.pred x)) ->
(forall x, P x).
Proof. intros H0 HS HP.
now apply (Z.order_induction' _ _ y).
Qed.
Definition lengthOrder {A : Type} (l1 l2 : list A) : Prop :=
length l1 < length l2.
Theorem lengthOrder_wf : forall (A : Type),
well_founded (@lengthOrder A).
Proof.
unfold lengthOrder. intro.
apply (@well_founded_lt_compat _ (@length A)). trivial.
Defined.
(* sublist wf induction *)
Inductive strictsublist {A : Type} : list A -> list A -> Prop :=
| strictsublist_nil : forall h t, strictsublist nil (h :: t)
| strictsublist_skip : forall l1 h t, strictsublist l1 t -> strictsublist l1 (h :: t)
| strictsublist_cons : forall h t1 t2, strictsublist t1 t2 -> strictsublist (h :: t1) (h :: t2).
Lemma strictsublist_wf (A : Type) :
well_founded (strictsublist (A := A)).
Proof.
eapply well_founded_lt_compat with (f := (length (A := A))).
intros l1 l2 H.
induction H; simpl; auto with arith.
Qed.
Lemma minus_le_O : forall a b : nat, a <= b -> a - b = 0.
Proof.
intros. pattern a, b in |- *.
apply le_elim_rel. auto with arith.
intros. simpl in |- *. exact H1.
exact H.
Qed.
Lemma minus_Sn_m : forall n m, m <= n -> S (n - m) = S n - m.
Proof.
intros n m Le; pattern m, n; apply le_elim_rel; simpl;
auto with arith.
Qed.