Make_triplets_def.v
Require Export EqNat.
Require Export Max.
Require Export Compare_dec.
Require Export Int.
Require Export Normalise.
Definition
egaux_avant :=
[n:nat] [f, g:nat ->bool] (k:nat) (le k n) ->(f k)=(g k).
Lemma
egaux_avant_elim:
(n:nat) (f, g:nat ->bool) (egaux_avant n f g) ->(f n)=(g n).
Intros; Unfold egaux_avant; Intros; Auto.
Qed.
Lemma
egaux_avant_refl: (n:nat) (f:nat ->bool)(egaux_avant n f f).
Intros; Unfold egaux_avant; Intros; Auto.
Qed.
Lemma
egaux_avant_trans:
(n:nat) (f, g, h:nat ->bool) (egaux_avant n f g) -> (egaux_avant n g h) ->
(egaux_avant n f h).
Unfold egaux_avant; Intros; Auto.
Rewrite (H k); Auto.
Qed.
Lemma
egaux_avant_crois:
(n, m:nat) (f, g:nat ->bool) (le n m) -> (egaux_avant m f g) ->
(egaux_avant n f g).
Unfold egaux_avant; Intros; Apply H0; Apply le_trans with n; Auto.
Qed.
Hint egaux_avant_elim egaux_avant_refl egaux_avant_trans egaux_avant_crois.
Lemma
egaux_avant_sym:
(n:nat) (f, g:nat ->bool) (egaux_avant n f g) ->(egaux_avant n g f).
Unfold egaux_avant; Intros; Auto.
Rewrite H; Auto.
Qed.
Hint egaux_avant_sym.
Lemma
egaux_avant_S:
(n:nat) (f, g:nat ->bool) (egaux_avant n f g) -> (f (S n))=(g (S n)) ->
(egaux_avant (S n) f g).
Unfold egaux_avant; Intros; Auto.
Case (le_lt_dec k n); Auto.
Intros.
Cut k=(S n); Auto.
Intros N; Rewrite N; Auto.
Qed.
Hint egaux_avant_S.
Fixpoint
max_var[e:expr2]: nat :=
Cases e of
T2 => O
| F2 => O
| (V2 n) => n
| (N2 p) => (max_var p)
| (Node2 n p q) => (max (max_var p) (max_var q))
end.
Theorem
th_le_max_var: (e:expr2) (n:nat) (in_expr2 n e) ->(le n (max_var e)).
Induction e; Intros.
Inversion H.
Inversion H.
Inversion H; Simpl; Auto.
Inversion H0; Simpl; Auto.
Inversion H1;
[Simpl; Apply le_trans with (max_var e0) |
Simpl; Apply le_trans with (max_var e1)]; Auto.
Qed.
Theorem
support2b:
(f, g:nat ->bool) (e:expr2) (egaux_avant (max_var e) f g) ->
(eval2 f e)=(eval2 g e).
Unfold egaux_avant; Intros; Apply support2; Intros; Apply H;
Apply th_le_max_var; Auto.
Qed.
Mutual Inductive
triplet: Set :=
Eq: node2 -> int -> int -> int ->triplet .
Definition
eval_triplet: (nat ->bool) -> triplet ->bool :=
[f:nat ->bool] [t:triplet]
Cases t of
(Eq n v1 v2 v3) =>
(eqb (eval_int f v1) ((f_assoc n) (eval_int f v2) (eval_int f v3)))
end.
Definition
max_var_triplet :=
[t:triplet]
Cases t of
(Eq n v1 v2 v3) =>
(max (nat_of_int v1) (max (nat_of_int v2) (nat_of_int v3)))
end.
Mutual Inductive
in_triplet: int -> triplet ->Prop :=
in_t1: (n:node2) (i1, i2, i3:int)(in_triplet i1 (Eq n i1 i2 i3))
| in_t2: (n:node2) (i1, i2, i3:int)(in_triplet i2 (Eq n i1 i2 i3))
| in_t3: (n:node2) (i1, i2, i3:int)(in_triplet i3 (Eq n i1 i2 i3)) .
Hint in_t1 in_t2 in_t3.
Lemma
th_max_var_triplet:
(t:triplet) (i:int) (in_triplet i t) ->(le (nat_of_int i) (max_var_triplet t)).
Intros.
Inversion H; Simpl; Auto.
Apply le_trans with (max (nat_of_int i) (nat_of_int i3)); Auto.
Apply le_trans with (max (nat_of_int i2) (nat_of_int i)); Auto.
Qed.
Hint th_max_var_triplet.
Lemma
th_eval_triplet:
(f, g:nat ->bool) (t:triplet) (egaux_avant (max_var_triplet t) f g) ->
(eval_triplet f t)=(eval_triplet g t).
Unfold egaux_avant; Intros f g t; Case t; Intros; Simpl; Auto.
Rewrite (th_eval_int f g i); Rewrite (th_eval_int f g i0);
Rewrite (th_eval_int f g i1); Auto.
Qed.
Hint th_eval_triplet.
Fixpoint
make_triplets_rec[e:expr2]:
(list triplet) -> nat ->(list triplet) * (int * nat) :=
[l:(list triplet)] [n:nat]
Cases e of
T2 => (l, (Un, n))
| F2 => (l, (Moins_Un, n))
| (V2 i) => (l, ((P i), n))
| (N2 p) => Cases (make_triplets_rec p l n) of
(pair l1 (pair s1 n1)) => (l1, ((moins s1), n1))
end
| (Node2 node p q) => Cases (make_triplets_rec p l n) of
(pair l1 (pair s1 n1)) =>
Cases (make_triplets_rec q l1 n1) of
(pair l2 (pair s2 n2)) =>
((cons (Eq node (P (S n2)) s1 s2) l2),
((P (S n2)), (S n2)))
end
end
end.
Definition
make_triplets: expr2 ->(list triplet) * (int * nat) :=
[e:expr2](make_triplets_rec e (nil triplet) (max_var e)).
Fixpoint
max_var_triplets[l:(list triplet)]: nat :=
Cases l of
nil => O
| (cons t q) => (max (max_var_triplet t) (max_var_triplets q))
end.
Mutual Inductive
realise_triplets: (nat ->bool) -> (list triplet) ->Prop :=
realise_nil: (f:nat ->bool)(realise_triplets f (nil triplet))
| realise_cons:
(f:nat ->bool)
(t:triplet)
(l:(list triplet)) (realise_triplets f l) -> (eval_triplet f t)=true ->
(realise_triplets f (cons t l)) .
Hint realise_nil realise_cons.
Lemma
realise_triplets_in_triplet:
(f:nat ->bool) (l:(list triplet))
(iff (realise_triplets f l) (t:triplet) (In t l) ->(eval_triplet f t)=true).
Split; Elim l; Auto.
Intros.
Absurd (In t (nil triplet)); Auto.
Intros.
Inversion H1; Inversion H0; Auto; Rewrite <- H2; Auto.
Qed.
Lemma
realise_crois:
(f:nat ->bool)
(l1, l2:(list triplet)) (realise_triplets f l1) -> (incl l2 l1) ->
(realise_triplets f l2).
Unfold incl.
Intros.
Case (realise_triplets_in_triplet f l1); Intros Lemme11 Lemme12.
Case (realise_triplets_in_triplet f l2); Intros Lemme21 Lemme22.
Apply Lemme22.
Intros t Ht.
Apply Lemme11; Auto.
Qed.
Lemma
max_var_triplets_crois:
(l:(list triplet)) (t:triplet)
(le (max_var_triplets l) (max_var_triplets (cons t l))).
Intros.
Unfold max_var_triplets.
Case l; Auto.
Qed.
Lemma
max_var_triplets_crois2:
(l:(list triplet)) (t:triplet)
(le (max_var_triplet t) (max_var_triplets (cons t l))).
Intros.
Unfold max_var_triplets.
Case l; Auto.
Qed.
Lemma
support_triplets:
(f, g:nat ->bool)
(l:(list triplet))
(realise_triplets f l) -> (egaux_avant (max_var_triplets l) f g) ->
(realise_triplets g l).
Induction l; Auto.
Intros; Apply realise_cons; Auto.
Apply H; Inversion H0; Auto.
Apply (egaux_avant_crois
(max_var_triplets l0) (max_var_triplets (cons a l0)) f g); Auto.
Apply max_var_triplets_crois.
Inversion H0; Auto.
Rewrite <- (th_eval_triplet f g a); Auto.
Apply (egaux_avant_crois (max_var_triplet a) (max_var_triplets (cons a l0)) f g);
Auto.
Apply max_var_triplets_crois2.
Qed.
Hint support_triplets.
Lemma
th_max_1:
(l:(list triplet))
(t:triplet)
(n:nat) (le (max_var_triplets l) n) -> (le (max_var_triplet t) n) ->
(le (max_var_triplets (cons t l)) n).
Intros.
Cut (max (max_var_triplet t) (max_var_triplets l))=(max_var_triplets (cons t l)).
Intros; Rewrite <- H1; Auto.
Apply (max_case_Prop (max_var_triplet t) (max_var_triplets l) [m:nat](le m n));
Auto.
Auto.
Qed.
Hint th_max_1.
Lemma
th_max_2:
(node:node2)
(i1, i2, i3:int)
(n:nat)
(le (nat_of_int i1) n) -> (le (nat_of_int i2) n) -> (le (nat_of_int i3) n) ->
(le (max_var_triplet (Eq node i1 i2 i3)) n).
Intros.
Unfold max_var_triplet.
Apply (max_case_Prop
(nat_of_int i1) (max (nat_of_int i2) (nat_of_int i3)) [m:nat](le m n));
Auto.
Apply (max_case_Prop (nat_of_int i2) (nat_of_int i3) [m:nat](le m n)); Auto.
Qed.
Hint th_max_2.
Lemma
th_le_max_int_n:
(e:expr2)
(l, l1:(list triplet))
(n, n1:nat)
(s1:int) (le (max_var e) n) -> (make_triplets_rec e l n)=(l1, (s1, n1)) ->
(le (nat_of_int s1) n1).
Induction e; Simpl; Auto.
Intros; Inversion H0; Simpl; Auto.
Intros; Inversion H0; Simpl; Auto.
Intros; Inversion H0; Simpl; Rewrite <- H4; Auto.
Intros e1 H1 l l2 n n2 s2 H.
Generalize (refl_equal (list triplet) * (int * nat) (make_triplets_rec e1 l n)).
Pattern 2 3 (make_triplets_rec e1 l n).
Case (make_triplets_rec e1 l n); Intros l1 p1.
Case p1; Intros s1 n1.
Intros Eg1 N; Inversion N; Auto.
Rewrite nat_of_int_moins.
Rewrite <- H4; Apply (H1 l l1 n n1 s1); Auto.
Intros node e1 H1 e2 H2 l l3 n n3 s3 H.
Case (make_triplets_rec e1 l n); Intros l1 p1.
Case p1; Intros s1 n1.
Case (make_triplets_rec e2 l1 n1); Intros l2 p2.
Case p2; Intros s2 n2.
Intros N; Inversion N; Auto.
Qed.
Hint th_le_max_int_n.
Lemma
make_crois:
(e:expr2)
(l, l':(list triplet))
(n, n':nat) (s':int) (make_triplets_rec e l n)=(l', (s', n')) ->(le n n').
Induction e;
[Intros l l' n n' s'; Simpl; Intros N; Inversion N |
Intros l l' n n' s'; Simpl; Intros N; Inversion N |
Intros n0 l l' n n' s'; Simpl; Intros N; Inversion N |
Intros e1 H1 l l' n n' s'; Simpl;
Generalize (refl_equal
(list triplet) * (int * nat) (make_triplets_rec e1 l n));
Pattern 2 3 (make_triplets_rec e1 l n); Case (make_triplets_rec e1 l n);
Intros l1 p1; Case p1; Intros s1 n1; Intros Eg1 N; Inversion N |
Intros node e1 H1 e2 H2 l l' n n' s'; Simpl;
Generalize (refl_equal
(list triplet) * (int * nat) (make_triplets_rec e1 l n));
Pattern 2 3 (make_triplets_rec e1 l n); Case (make_triplets_rec e1 l n);
Intros l1 p1; Case p1; Intros s1 n1; Intros Eg1;
Generalize (refl_equal
(list triplet) * (int * nat) (make_triplets_rec e2 l1 n1));
Pattern 2 3 (make_triplets_rec e2 l1 n1); Case (make_triplets_rec e2 l1 n1);
Intros l2 p2; Case p2; Intros s2 n2; Intros Eg2 N; Inversion N]; Auto.
Rewrite <- H3; Auto.
Apply (H1 l l1 n n1 s1); Auto.
Apply le_trans with n2; Auto.
Apply le_trans with n1; Auto.
Apply (H1 l l1 n n1 s1); Auto.
Apply (H2 l1 l2 n1 n2 s2); Auto.
Qed.
Hint make_crois.
Lemma
make_crois2:
(e:expr2)
(l, l1:(list triplet))
(n, n1:nat) (s1:int) (make_triplets_rec e l n)=(l1, (s1, n1)) ->(incl l l1).
Induction e;
[Intros l l' n n' s'; Simpl; Intros N; Inversion N |
Intros l l' n n' s'; Simpl; Intros N; Inversion N |
Intros n0 l l' n n' s'; Simpl; Intros N; Inversion N |
Intros e1 H1 l l' n n' s'; Simpl;
Generalize (refl_equal
(list triplet) * (int * nat) (make_triplets_rec e1 l n));
Pattern 2 3 (make_triplets_rec e1 l n); Case (make_triplets_rec e1 l n);
Intros l1 p1; Case p1; Intros s1 n1; Intros Eg1 N; Inversion N |
Intros node e1 H1 e2 H2 l l' n n' s'; Simpl;
Generalize (refl_equal
(list triplet) * (int * nat) (make_triplets_rec e1 l n));
Pattern 2 3 (make_triplets_rec e1 l n); Case (make_triplets_rec e1 l n);
Intros l1 p1; Case p1; Intros s1 n1; Intros Eg1;
Generalize (refl_equal
(list triplet) * (int * nat) (make_triplets_rec e2 l1 n1));
Pattern 2 3 (make_triplets_rec e2 l1 n1); Case (make_triplets_rec e2 l1 n1);
Intros l2 p2; Case p2; Intros s2 n2; Intros Eg2 N; Inversion N]; Auto.
Rewrite <- H0; Auto.
Apply (H1 l l1 n n1 s1); Auto.
Apply incl_tl; Auto.
Apply incl_tran with l1; Auto.
Apply (H1 l l1 n n1 s1); Auto.
Apply (H2 l1 l2 n1 n2 s2); Auto.
Qed.
Hint make_crois2.
Lemma
max_var_e1:
(n:node2) (e1, e2:expr2)(le (max_var e1) (max_var (Node2 n e1 e2))).
Intros.
Cut (max_var (Node2 n e1 e2))=(max (max_var e1) (max_var e2)); Auto.
Intros A; Rewrite A; Auto.
Qed.
Lemma
max_var_e2:
(n:node2) (e1, e2:expr2)(le (max_var e2) (max_var (Node2 n e1 e2))).
Intros.
Cut (max_var (Node2 n e1 e2))=(max (max_var e1) (max_var e2)); Auto.
Intros A; Rewrite A; Auto.
Qed.
Hint max_var_e1 max_var_e2.
Lemma
max_var_triplets_le:
(e:expr2)
(l, l':(list triplet))
(n, n':nat)
(s':int)
(le (max_var e) n) ->
(le (max_var_triplets l) n) -> (make_triplets_rec e l n)=(l', (s', n')) ->
(le (max_var_triplets l') n').
Induction e;
[Intros l l' n n' s' Hyp0 Hyp1; Simpl; Intros N; Inversion N |
Intros l l' n n' s' Hyp0 Hyp1; Simpl; Intros N; Inversion N |
Intros n0 l l' n n' s' Hyp0 Hyp1; Simpl; Intros N; Inversion N |
Intros e1 H1 l l' n n' s' Hyp0 Hyp1; Simpl;
Generalize (refl_equal
(list triplet) * (int * nat) (make_triplets_rec e1 l n));
Pattern 2 3 (make_triplets_rec e1 l n); Case (make_triplets_rec e1 l n);
Intros l1 p1; Case p1; Intros s1 n1; Intros Eg1 N; Inversion N |
Intros node e1 H1 e2 H2 l l' n n' s' Hyp0 Hyp1; Simpl;
Generalize (refl_equal
(list triplet) * (int * nat) (make_triplets_rec e1 l n));
Pattern 2 3 (make_triplets_rec e1 l n); Case (make_triplets_rec e1 l n);
Intros l1 p1; Case p1; Intros s1 n1; Intros Eg1;
Generalize (refl_equal
(list triplet) * (int * nat) (make_triplets_rec e2 l1 n1));
Pattern 2 3 (make_triplets_rec e2 l1 n1); Case (make_triplets_rec e2 l1 n1);
Intros l2 p2; Case p2; Intros s2 n2; Intros Eg2 N; Inversion N]; Auto.
Rewrite <- H2; Rewrite <- H0; Auto.
Rewrite <- H2; Rewrite <- H0; Auto.
Rewrite <- H2; Rewrite <- H0; Auto.
Rewrite <- H3; Rewrite <- H0; Auto.
Apply (H1 l l1 n n1 s1); Auto.
Apply th_max_1.
Apply le_trans with n2; Auto.
Apply (H2 l1 l2 n1 n2 s2); Auto.
Apply le_trans with (max_var (Node2 node e1 e2)); Auto.
Apply le_trans with n; Auto.
Apply (make_crois e1 l l1 n n1 s1); Auto.
Apply (H1 l l1 n n1 s1); Auto.
Apply le_trans with (max_var (Node2 node e1 e2)); Auto.
Apply th_max_2; Auto.
Apply le_trans with n1; Auto.
Apply (th_le_max_int_n e1 l l1 n n1 s1); Auto.
Apply le_trans with (max_var (Node2 node e1 e2)); Auto.
Apply le_trans with n2; Auto.
Apply (make_crois e2 l1 l2 n1 n2 s2); Auto.
Apply le_trans with n2; Auto.
Apply (th_le_max_int_n e2 l1 l2 n1 n2 s2); Auto.
Apply le_trans with (max_var (Node2 node e1 e2)); Auto.
Apply le_trans with n; Auto.
Apply (make_crois e1 l l1 n n1 s1); Auto.
Qed.
Definition
solution :=
[n:nat] [g:nat ->bool] [s:bool] [m:nat]
Cases (le_lt_dec m n) of
left => (g m)
| right => s
end.
Lemma
egaux_avant_sol:
(g:nat ->bool) (n:nat) (s:bool)(egaux_avant n g (solution n g s)).
Intros.
Unfold egaux_avant; Intros k Hk.
Intros; Unfold solution.
Case (le_lt_dec k n); Auto.
Intros HA.
Absurd (lt n k); Auto.
Qed.
Hint egaux_avant_sol.
14/09/98, 09:21