1
(************************************************************************)
2
(* v * The Coq Proof Assistant / The Coq Development Team *)
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
4
(* \VV/ **************************************************************)
5
(* // * This file is distributed under the terms of the *)
6
(* * GNU Lesser General Public License Version 2.1 *)
7
(************************************************************************)
9
(* Micromega: A reflexive tactic using the Positivstellensatz *)
11
(* Frédéric Besson (Irisa/Inria) 2006-2008 *)
13
(************************************************************************)
19
Set Implicit Arguments.
22
Inductive BFormula (A:Type) : Type :=
25
| X : Prop -> BFormula A
27
| Cj : BFormula A -> BFormula A -> BFormula A
28
| D : BFormula A-> BFormula A -> BFormula A
29
| N : BFormula A -> BFormula A
30
| I : BFormula A-> BFormula A-> BFormula A.
32
Fixpoint eval_f (A:Type) (ev:A -> Prop ) (f:BFormula A) {struct f}: Prop :=
38
| Cj e1 e2 => (eval_f ev e1) /\ (eval_f ev e2)
39
| D e1 e2 => (eval_f ev e1) \/ (eval_f ev e2)
40
| N e => ~ (eval_f ev e)
41
| I f1 f2 => (eval_f ev f1) -> (eval_f ev f2)
45
Lemma map_simpl : forall A B f l, @map A B f l = match l with
47
| a :: l=> (f a) :: (@map A B f l)
50
destruct l ; reflexivity.
59
Variable eval : Env -> Term -> Prop.
60
Variable Term' : Type.
61
Variable eval' : Env -> Term' -> Prop.
65
Variable no_middle_eval' : forall env d, (eval' env d) \/ ~ (eval' env d).
68
Definition clause := list Term'.
69
Definition cnf := list clause.
71
Variable normalise : Term -> cnf.
72
Variable negate : Term -> cnf.
75
Definition tt : cnf := @nil clause.
76
Definition ff : cnf := cons (@nil Term') nil.
79
Definition or_clause_cnf (t:clause) (f:cnf) : cnf :=
80
List.map (fun x => (t++x)) f.
82
Fixpoint or_cnf (f : cnf) (f' : cnf) {struct f}: cnf :=
85
| e :: rst => (or_cnf rst f') ++ (or_clause_cnf e f')
89
Definition and_cnf (f1 : cnf) (f2 : cnf) : cnf :=
92
Fixpoint xcnf (pol : bool) (f : BFormula Term) {struct f}: cnf :=
94
| TT => if pol then tt else ff
95
| FF => if pol then ff else tt
96
| X p => if pol then ff else ff (* This is not complete - cannot negate any proposition *)
97
| A x => if pol then normalise x else negate x
98
| N e => xcnf (negb pol) e
100
(if pol then and_cnf else or_cnf) (xcnf pol e1) (xcnf pol e2)
101
| D e1 e2 => (if pol then or_cnf else and_cnf) (xcnf pol e1) (xcnf pol e2)
102
| I e1 e2 => (if pol then or_cnf else and_cnf) (xcnf (negb pol) e1) (xcnf pol e2)
105
Definition eval_cnf (env : Term' -> Prop) (f:cnf) := make_conj (fun cl => ~ make_conj env cl) f.
108
Lemma eval_cnf_app : forall env x y, eval_cnf (eval' env) (x++y) -> eval_cnf (eval' env) x /\ eval_cnf (eval' env) y.
112
rewrite make_conj_app in H ; auto.
116
Lemma or_clause_correct : forall env t f, eval_cnf (eval' env) (or_clause_cnf t f) -> (~ make_conj (eval' env) t) \/ (eval_cnf (eval' env) f).
119
unfold or_clause_cnf.
126
rewrite make_conj_cons in H.
127
destruct H as [HH1 HH2].
128
generalize (IHf HH2) ; clear IHf ; intro.
131
rewrite make_conj_cons.
132
destruct (not_make_conj_app _ _ _ (no_middle_eval' env) HH1).
137
Lemma eval_cnf_cons : forall env a f, (~ make_conj (eval' env) a) -> eval_cnf (eval' env) f -> eval_cnf (eval' env) (a::f).
140
unfold eval_cnf in *.
141
rewrite make_conj_cons ; eauto.
144
Lemma or_cnf_correct : forall env f f', eval_cnf (eval' env) (or_cnf f f') -> (eval_cnf (eval' env) f) \/ (eval_cnf (eval' env) f').
153
destruct (eval_cnf_app _ _ _ H).
156
destruct (or_clause_correct _ _ _ H1).
158
apply eval_cnf_cons ; auto.
163
Variable normalise_correct : forall env t, eval_cnf (eval' env) (normalise t) -> eval env t.
165
Variable negate_correct : forall env t, eval_cnf (eval' env) (negate t) -> ~ eval env t.
168
Lemma xcnf_correct : forall f pol env, eval_cnf (eval' env) (xcnf pol f) -> eval_f (eval env) (if pol then f else N f).
174
destruct pol ; simpl ; auto.
177
destruct pol; simpl ; auto.
180
destruct pol ; intros ;simpl.
181
unfold eval_cnf in H.
182
(* Here I have to drop the proposition *)
185
(* Here, I could store P in the clause *)
186
unfold eval_cnf in H;simpl in H.
190
destruct pol ; simpl.
192
apply normalise_correct ; auto.
195
apply negate_correct ; auto.
198
destruct pol ; simpl.
202
destruct (eval_cnf_app _ _ _ H).
209
destruct (or_cnf_correct _ _ _ H).
210
generalize (IHf1 false env H0).
213
generalize (IHf2 false env H0).
221
destruct (or_cnf_correct _ _ _ H).
222
generalize (IHf1 _ env H0).
225
generalize (IHf2 _ env H0).
231
destruct (eval_cnf_app _ _ _ H).
234
generalize (IHf1 _ _ H0).
235
generalize (IHf2 _ _ H1).
240
destruct pol ; simpl.
242
apply (IHf false) ; auto.
244
generalize (IHf _ _ H).
251
destruct (or_cnf_correct _ _ _ H).
252
generalize (IHf1 _ _ H1).
255
generalize (IHf2 _ _ H1).
260
destruct (eval_cnf_app _ _ _ H).
261
generalize (IHf1 _ _ H0).
262
generalize (IHf2 _ _ H1).
268
Variable Witness : Type.
269
Variable checker : list Term' -> Witness -> bool.
271
Variable checker_sound : forall t w, checker t w = true -> forall env, make_impl (eval' env) t False.
273
Fixpoint cnf_checker (f : cnf) (l : list Witness) {struct f}: bool :=
276
| e::f => match l with
278
| c::l => match checker e c with
279
| true => cnf_checker f l
285
Lemma cnf_checker_sound : forall t w, cnf_checker t w = true -> forall env, eval_cnf (eval' env) t.
295
intros ; discriminate.
296
case_eq (checker a w) ; intros ; try discriminate.
297
generalize (@checker_sound _ _ H env).
298
generalize (IHt _ H0 env) ; intros.
301
rewrite <- make_conj_impl in H2.
303
rewrite <- make_conj_impl in H2.
308
Definition tauto_checker (f:BFormula Term) (w:list Witness) : bool :=
309
cnf_checker (xcnf true f) w.
311
Lemma tauto_checker_sound : forall t w, tauto_checker t w = true -> forall env, eval_f (eval env) t.
313
unfold tauto_checker.
315
change (eval_f (eval env) t) with (eval_f (eval env) (if true then t else TT Term)).
316
apply (xcnf_correct t true).
317
eapply cnf_checker_sound ; eauto.