aboutsummaryrefslogtreecommitdiff
path: root/theories
diff options
context:
space:
mode:
authorMaxime Dénès2020-06-15 11:46:25 +0200
committerMaxime Dénès2020-06-15 11:46:25 +0200
commit90345eb092f9e3fc7ef1bdfe7f61cb913cb53d18 (patch)
tree98e649d22b8342a4c675a8077c372c8fc4dec34f /theories
parent61b63e09e4b5ce428bc8e8c038efe93560f328ff (diff)
parent12e9f7ea1a2ae3111805fc42f8d75a1a24c36e3f (diff)
Merge PR #11906: [micromega] native support for boolean operators
Reviewed-by: maximedenes Reviewed-by: pi8027 Reviewed-by: vbgl
Diffstat (limited to 'theories')
-rw-r--r--theories/Bool/Bool.v2
-rw-r--r--theories/Init/Datatypes.v1
-rw-r--r--theories/ZArith/BinInt.v7
-rw-r--r--theories/micromega/Lia.v2
-rw-r--r--theories/micromega/QMicromega.v73
-rw-r--r--theories/micromega/RMicromega.v124
-rw-r--r--theories/micromega/Tauto.v2247
-rw-r--r--theories/micromega/ZMicromega.v78
-rw-r--r--theories/micromega/ZifyBool.v261
-rw-r--r--theories/micromega/ZifyClasses.v45
-rw-r--r--theories/micromega/ZifyComparison.v14
-rw-r--r--theories/micromega/ZifyInst.v231
12 files changed, 1882 insertions, 1203 deletions
diff --git a/theories/Bool/Bool.v b/theories/Bool/Bool.v
index d70978fabe..9e10786fcd 100644
--- a/theories/Bool/Bool.v
+++ b/theories/Bool/Bool.v
@@ -130,6 +130,8 @@ Definition eqb (b1 b2:bool) : bool :=
| false, false => true
end.
+Register eqb as core.bool.eqb.
+
Lemma eqb_subst :
forall (P:bool -> Prop) (b1 b2:bool), eqb b1 b2 = true -> P b1 -> P b2.
Proof.
diff --git a/theories/Init/Datatypes.v b/theories/Init/Datatypes.v
index cba90043d5..8ab12ae534 100644
--- a/theories/Init/Datatypes.v
+++ b/theories/Init/Datatypes.v
@@ -73,6 +73,7 @@ Infix "&&" := andb : bool_scope.
Register andb as core.bool.andb.
Register orb as core.bool.orb.
+Register implb as core.bool.implb.
Register xorb as core.bool.xorb.
Register negb as core.bool.negb.
diff --git a/theories/ZArith/BinInt.v b/theories/ZArith/BinInt.v
index 1729b9f85e..a566348dd5 100644
--- a/theories/ZArith/BinInt.v
+++ b/theories/ZArith/BinInt.v
@@ -47,6 +47,8 @@ Register mul as num.Z.mul.
Register pow as num.Z.pow.
Register of_nat as num.Z.of_nat.
+
+
(** When including property functors, only inline t eq zero one two *)
Set Inline Level 30.
@@ -81,6 +83,11 @@ Register le as num.Z.le.
Register lt as num.Z.lt.
Register ge as num.Z.ge.
Register gt as num.Z.gt.
+Register leb as num.Z.leb.
+Register ltb as num.Z.ltb.
+Register geb as num.Z.geb.
+Register gtb as num.Z.gtb.
+Register eqb as num.Z.eqb.
(** * Decidability of equality. *)
diff --git a/theories/micromega/Lia.v b/theories/micromega/Lia.v
index 3d955fec4f..b2c5884ed7 100644
--- a/theories/micromega/Lia.v
+++ b/theories/micromega/Lia.v
@@ -19,7 +19,6 @@ Require Import BinNums.
Require Coq.micromega.Tauto.
Declare ML Module "micromega_plugin".
-
Ltac zchecker :=
intros ?__wit ?__varmap ?__ff ;
exact (ZTautoChecker_sound __ff __wit
@@ -30,7 +29,6 @@ Ltac lia := Zify.zify; xlia zchecker.
Ltac nia := Zify.zify; xnlia zchecker.
-
(* Local Variables: *)
(* coding: utf-8 *)
(* End: *)
diff --git a/theories/micromega/QMicromega.v b/theories/micromega/QMicromega.v
index 1fbc5a648a..1bb016da9a 100644
--- a/theories/micromega/QMicromega.v
+++ b/theories/micromega/QMicromega.v
@@ -10,7 +10,7 @@
(* *)
(* Micromega: A reflexive tactic using the Positivstellensatz *)
(* *)
-(* Frédéric Besson (Irisa/Inria) 2006-2008 *)
+(* Frédéric Besson (Irisa/Inria) *)
(* *)
(************************************************************************)
@@ -107,7 +107,7 @@ Proof.
apply QNpower.
Qed.
-Definition Qeval_op2 (o : Op2) : Q -> Q -> Prop :=
+Definition Qeval_pop2 (o : Op2) : Q -> Q -> Prop :=
match o with
| OpEq => Qeq
| OpNEq => fun x y => ~ x == y
@@ -117,13 +117,63 @@ match o with
| OpGt => fun x y => Qlt y x
end.
-Definition Qeval_formula (e:PolEnv Q) (ff : Formula Q) :=
- let (lhs,o,rhs) := ff in Qeval_op2 o (Qeval_expr e lhs) (Qeval_expr e rhs).
+
+Definition Qlt_bool (x y : Q) :=
+ (Qnum x * QDen y <? Qnum y * QDen x)%Z.
+
+Definition Qeval_bop2 (o : Op2) : Q -> Q -> bool :=
+ match o with
+ | OpEq => Qeq_bool
+ | OpNEq => fun x y => negb (Qeq_bool x y)
+ | OpLe => Qle_bool
+ | OpGe => fun x y => Qle_bool y x
+ | OpLt => Qlt_bool
+ | OpGt => fun x y => Qlt_bool y x
+ end.
+
+Lemma Qlt_bool_iff : forall q1 q2,
+ Qlt_bool q1 q2 = true <-> q1 < q2.
+Proof.
+ unfold Qlt_bool.
+ unfold Qlt. intros.
+ apply Z.ltb_lt.
+Qed.
+
+Lemma pop2_bop2 :
+ forall (op : Op2) (q1 q2 : Q), is_true (Qeval_bop2 op q1 q2) <-> Qeval_pop2 op q1 q2.
+Proof.
+ unfold is_true.
+ destruct op ; simpl; intros.
+ - apply Qeq_bool_iff.
+ - rewrite <- Qeq_bool_iff.
+ rewrite negb_true_iff.
+ destruct (Qeq_bool q1 q2) ; intuition congruence.
+ - apply Qle_bool_iff.
+ - apply Qle_bool_iff.
+ - apply Qlt_bool_iff.
+ - apply Qlt_bool_iff.
+Qed.
+
+Definition Qeval_op2 (k:Tauto.kind) : Op2 -> Q -> Q -> Tauto.rtyp k:=
+ if k as k0 return (Op2 -> Q -> Q -> Tauto.rtyp k0)
+ then Qeval_pop2 else Qeval_bop2.
+
+
+Lemma Qeval_op2_hold : forall k op q1 q2,
+ Tauto.hold k (Qeval_op2 k op q1 q2) <-> Qeval_pop2 op q1 q2.
+Proof.
+ destruct k.
+ simpl ; tauto.
+ simpl. apply pop2_bop2.
+Qed.
+
+Definition Qeval_formula (e:PolEnv Q) (k: Tauto.kind) (ff : Formula Q) :=
+ let (lhs,o,rhs) := ff in Qeval_op2 k o (Qeval_expr e lhs) (Qeval_expr e rhs).
Definition Qeval_formula' :=
eval_formula Qplus Qmult Qminus Qopp Qeq Qle Qlt (fun x => x) (fun x => x) (pow_N 1 Qmult).
-Lemma Qeval_formula_compat : forall env f, Qeval_formula env f <-> Qeval_formula' env f.
+ Lemma Qeval_formula_compat : forall env b f, Tauto.hold b (Qeval_formula env b f) <-> Qeval_formula' env f.
Proof.
intros.
unfold Qeval_formula.
@@ -131,6 +181,8 @@ Proof.
repeat rewrite Qeval_expr_compat.
unfold Qeval_formula'.
unfold Qeval_expr'.
+ simpl.
+ rewrite Qeval_op2_hold.
split ; destruct Fop ; simpl; auto.
Qed.
@@ -186,10 +238,10 @@ Definition qdeduce := nformula_plus_nformula 0 Qplus Qeq_bool.
Definition normQ := norm 0 1 Qplus Qmult Qminus Qopp Qeq_bool.
Declare Equivalent Keys normQ RingMicromega.norm.
-Definition cnfQ (Annot TX AF: Type) (f: TFormula (Formula Q) Annot TX AF) :=
+Definition cnfQ (Annot:Type) (TX: Tauto.kind -> Type) (AF: Type) (k: Tauto.kind) (f: TFormula (Formula Q) Annot TX AF k) :=
rxcnf qunsat qdeduce (Qnormalise Annot) (Qnegate Annot) true f.
-Definition QTautoChecker (f : BFormula (Formula Q)) (w: list QWitness) : bool :=
+Definition QTautoChecker (f : BFormula (Formula Q) Tauto.isProp) (w: list QWitness) : bool :=
@tauto_checker (Formula Q) (NFormula Q) unit
qunsat qdeduce
(Qnormalise unit)
@@ -208,8 +260,11 @@ Proof.
destruct t.
apply (check_inconsistent_sound Qsor QSORaddon) ; auto.
- unfold qdeduce. intros. revert H. apply (nformula_plus_nformula_correct Qsor QSORaddon);auto.
- - intros. rewrite Qeval_formula_compat. unfold Qeval_formula'. now eapply (cnf_normalise_correct Qsor QSORaddon);eauto.
- - intros. rewrite Qeval_formula_compat. unfold Qeval_formula'. now eapply (cnf_negate_correct Qsor QSORaddon);eauto.
+ - intros.
+ rewrite Qeval_formula_compat.
+ eapply (cnf_normalise_correct Qsor QSORaddon) ; eauto.
+ - intros. rewrite Tauto.hold_eNOT. rewrite Qeval_formula_compat.
+ now eapply (cnf_negate_correct Qsor QSORaddon);eauto.
- intros t w0.
unfold eval_tt.
intros.
diff --git a/theories/micromega/RMicromega.v b/theories/micromega/RMicromega.v
index fd8903eac9..7e2694a519 100644
--- a/theories/micromega/RMicromega.v
+++ b/theories/micromega/RMicromega.v
@@ -10,19 +10,18 @@
(* *)
(* Micromega: A reflexive tactic using the Positivstellensatz *)
(* *)
-(* Frédéric Besson (Irisa/Inria) 2006-2008 *)
+(* Frédéric Besson (Irisa/Inria) *)
(* *)
(************************************************************************)
Require Import OrderedRing.
-Require Import RingMicromega.
+Require Import QMicromega RingMicromega.
Require Import Refl.
-Require Import Raxioms Rfunctions RIneq Rpow_def.
+Require Import Sumbool Raxioms Rfunctions RIneq Rpow_def.
Require Import QArith.
Require Import Qfield.
Require Import Qreals.
Require Import DeclConstant.
-Require Import Ztac.
Require Setoid.
(*Declare ML Module "micromega_plugin".*)
@@ -344,16 +343,17 @@ Proof.
apply Qeq_bool_eq in C2.
rewrite C2.
simpl.
- rewrite Qpower0.
+ assert (z <> 0%Z).
+ { intro ; subst. apply Z.lt_irrefl in C1. auto. }
+ rewrite Qpower0 by auto.
apply Q2R_0.
- intro ; subst ; slia C1 C1.
+ rewrite Q2RpowerRZ.
rewrite IHc.
reflexivity.
rewrite andb_false_iff in C.
destruct C.
simpl. apply Z.ltb_ge in H.
- right ; normZ. slia H H0.
+ right. Ztac.normZ. Ztac.slia H H0.
left ; apply Qeq_bool_neq; auto.
+ simpl.
rewrite <- IHc.
@@ -382,7 +382,7 @@ Definition INZ (n:N) : R :=
Definition Reval_expr := eval_pexpr Rplus Rmult Rminus Ropp R_of_Rcst N.to_nat pow.
-Definition Reval_op2 (o:Op2) : R -> R -> Prop :=
+Definition Reval_pop2 (o:Op2) : R -> R -> Prop :=
match o with
| OpEq => @eq R
| OpNEq => fun x y => ~ x = y
@@ -392,27 +392,91 @@ Definition Reval_op2 (o:Op2) : R -> R -> Prop :=
| OpGt => Rgt
end.
+Definition sumboolb {A B : Prop} (x : @sumbool A B) : bool :=
+ if x then true else false.
-Definition Reval_formula (e: PolEnv R) (ff : Formula Rcst) :=
- let (lhs,o,rhs) := ff in Reval_op2 o (Reval_expr e lhs) (Reval_expr e rhs).
+
+Definition Reval_bop2 (o : Op2) : R -> R -> bool :=
+ match o with
+ | OpEq => fun x y => sumboolb (Req_EM_T x y)
+ | OpNEq => fun x y => negb (sumboolb (Req_EM_T x y))
+ | OpLe => fun x y => (sumboolb (Rle_lt_dec x y))
+ | OpGe => fun x y => (sumboolb (Rge_gt_dec x y))
+ | OpLt => fun x y => (sumboolb (Rlt_le_dec x y))
+ | OpGt => fun x y => (sumboolb (Rgt_dec x y))
+ end.
+
+Lemma pop2_bop2 :
+ forall (op : Op2) (r1 r2 : R), is_true (Reval_bop2 op r1 r2) <-> Reval_pop2 op r1 r2.
+Proof.
+ unfold is_true.
+ destruct op ; simpl; intros;
+ match goal with
+ | |- context[sumboolb (?F ?X ?Y)] =>
+ destruct (F X Y) ; simpl; intuition try congruence
+ end.
+ - apply Rlt_not_le in r. tauto.
+ - apply Rgt_not_ge in r. tauto.
+ - apply Rlt_not_le in H. tauto.
+Qed.
+
+Definition Reval_op2 (k: Tauto.kind) : Op2 -> R -> R -> Tauto.rtyp k:=
+ if k as k0 return (Op2 -> R -> R -> Tauto.rtyp k0)
+ then Reval_pop2 else Reval_bop2.
+
+Lemma Reval_op2_hold : forall b op q1 q2,
+ Tauto.hold b (Reval_op2 b op q1 q2) <-> Reval_pop2 op q1 q2.
+Proof.
+ destruct b.
+ simpl ; tauto.
+ simpl. apply pop2_bop2.
+Qed.
+
+Definition Reval_formula (e: PolEnv R) (k: Tauto.kind) (ff : Formula Rcst) :=
+ let (lhs,o,rhs) := ff in Reval_op2 k o (Reval_expr e lhs) (Reval_expr e rhs).
Definition Reval_formula' :=
eval_sformula Rplus Rmult Rminus Ropp (@eq R) Rle Rlt N.to_nat pow R_of_Rcst.
-Definition QReval_formula :=
- eval_formula Rplus Rmult Rminus Ropp (@eq R) Rle Rlt Q2R N.to_nat pow .
+Lemma Reval_pop2_eval_op2 : forall o e1 e2,
+ Reval_pop2 o e1 e2 <->
+ eval_op2 eq Rle Rlt o e1 e2.
+Proof.
+ destruct o ; simpl ; try tauto.
+ split.
+ apply Rge_le.
+ apply Rle_ge.
+Qed.
-Lemma Reval_formula_compat : forall env f, Reval_formula env f <-> Reval_formula' env f.
+Lemma Reval_formula_compat : forall env b f, Tauto.hold b (Reval_formula env b f) <-> Reval_formula' env f.
Proof.
intros.
unfold Reval_formula.
destruct f.
unfold Reval_formula'.
- unfold Reval_expr.
- split ; destruct Fop ; simpl ; auto.
- apply Rge_le.
- apply Rle_ge.
+ simpl.
+ rewrite Reval_op2_hold.
+ apply Reval_pop2_eval_op2.
+Qed.
+
+Definition QReval_expr := eval_pexpr Rplus Rmult Rminus Ropp Q2R to_nat pow.
+
+Definition QReval_formula (e: PolEnv R) (k: Tauto.kind) (ff : Formula Q) :=
+ let (lhs,o,rhs) := ff in Reval_op2 k o (QReval_expr e lhs) (QReval_expr e rhs).
+
+
+Definition QReval_formula' :=
+ eval_formula Rplus Rmult Rminus Ropp (@eq R) Rle Rlt Q2R N.to_nat pow.
+
+Lemma QReval_formula_compat : forall env b f, Tauto.hold b (QReval_formula env b f) <-> QReval_formula' env f.
+Proof.
+ intros.
+ unfold QReval_formula.
+ destruct f.
+ unfold QReval_formula'.
+ rewrite Reval_op2_hold.
+ apply Reval_pop2_eval_op2.
Qed.
Definition Qeval_nformula :=
@@ -451,7 +515,7 @@ Definition runsat := check_inconsistent 0%Q Qeq_bool Qle_bool.
Definition rdeduce := nformula_plus_nformula 0%Q Qplus Qeq_bool.
-Definition RTautoChecker (f : BFormula (Formula Rcst)) (w: list RWitness) : bool :=
+Definition RTautoChecker (f : BFormula (Formula Rcst) Tauto.isProp) (w: list RWitness) : bool :=
@tauto_checker (Formula Q) (NFormula Q)
unit runsat rdeduce
(Rnormalise unit) (Rnegate unit)
@@ -463,18 +527,20 @@ Proof.
unfold RTautoChecker.
intros TC env.
apply tauto_checker_sound with (eval:=QReval_formula) (eval':= Qeval_nformula) (env := env) in TC.
- - change (eval_f (fun x : Prop => x) (QReval_formula env))
+ - change (eval_f e_rtyp (QReval_formula env))
with
(eval_bf (QReval_formula env)) in TC.
rewrite eval_bf_map in TC.
unfold eval_bf in TC.
rewrite eval_f_morph with (ev':= Reval_formula env) in TC ; auto.
- intro.
- unfold QReval_formula.
- rewrite <- eval_formulaSC with (phiS := R_of_Rcst).
- rewrite Reval_formula_compat.
- tauto.
- intro. rewrite Q_of_RcstR. reflexivity.
+ intros.
+ apply Tauto.hold_eiff.
+ rewrite QReval_formula_compat.
+ unfold QReval_formula'.
+ rewrite <- eval_formulaSC with (phiS := R_of_Rcst).
+ rewrite Reval_formula_compat.
+ tauto.
+ intro. rewrite Q_of_RcstR. reflexivity.
-
apply Reval_nformula_dec.
- destruct t.
@@ -482,8 +548,12 @@ Proof.
- unfold rdeduce.
intros. revert H.
eapply (nformula_plus_nformula_correct Rsor QSORaddon); eauto.
- - now apply (cnf_normalise_correct Rsor QSORaddon).
- - intros. now eapply (cnf_negate_correct Rsor QSORaddon); eauto.
+ -
+ intros.
+ rewrite QReval_formula_compat.
+ eapply (cnf_normalise_correct Rsor QSORaddon) ; eauto.
+ - intros. rewrite Tauto.hold_eNOT. rewrite QReval_formula_compat.
+ now eapply (cnf_negate_correct Rsor QSORaddon); eauto.
- intros t w0.
unfold eval_tt.
intros.
diff --git a/theories/micromega/Tauto.v b/theories/micromega/Tauto.v
index 6e89089355..dddced5739 100644
--- a/theories/micromega/Tauto.v
+++ b/theories/micromega/Tauto.v
@@ -17,49 +17,64 @@
Require Import List.
Require Import Refl.
Require Import Bool.
+Require Import Relation_Definitions Setoid.
Set Implicit Arguments.
+(** Formulae are either interpreted over Prop or bool. *)
+Inductive kind : Type :=
+|isProp
+|isBool.
+
+Register isProp as micromega.kind.isProp.
+Register isBool as micromega.kind.isBool.
+
Section S.
Context {TA : Type}. (* type of interpreted atoms *)
- Context {TX : Type}. (* type of uninterpreted terms (Prop) *)
+ Context {TX : kind -> Type}. (* type of uninterpreted terms (Prop) *)
Context {AA : Type}. (* type of annotations for atoms *)
Context {AF : Type}. (* type of formulae identifiers *)
- Inductive GFormula : Type :=
- | TT : GFormula
- | FF : GFormula
- | X : TX -> GFormula
- | A : TA -> AA -> GFormula
- | Cj : GFormula -> GFormula -> GFormula
- | D : GFormula -> GFormula -> GFormula
- | N : GFormula -> GFormula
- | I : GFormula -> option AF -> GFormula -> GFormula.
+ Inductive GFormula : kind -> Type :=
+ | TT : forall (k: kind), GFormula k
+ | FF : forall (k: kind), GFormula k
+ | X : forall (k: kind), TX k -> GFormula k
+ | A : forall (k: kind), TA -> AA -> GFormula k
+ | AND : forall (k: kind), GFormula k -> GFormula k -> GFormula k
+ | OR : forall (k: kind), GFormula k -> GFormula k -> GFormula k
+ | NOT : forall (k: kind), GFormula k -> GFormula k
+ | IMPL : forall (k: kind), GFormula k -> option AF -> GFormula k -> GFormula k
+ | IFF : forall (k: kind), GFormula k -> GFormula k -> GFormula k
+ | EQ : GFormula isBool -> GFormula isBool -> GFormula isProp.
Register TT as micromega.GFormula.TT.
Register FF as micromega.GFormula.FF.
Register X as micromega.GFormula.X.
Register A as micromega.GFormula.A.
- Register Cj as micromega.GFormula.Cj.
- Register D as micromega.GFormula.D.
- Register N as micromega.GFormula.N.
- Register I as micromega.GFormula.I.
+ Register AND as micromega.GFormula.AND.
+ Register OR as micromega.GFormula.OR.
+ Register NOT as micromega.GFormula.NOT.
+ Register IMPL as micromega.GFormula.IMPL.
+ Register IFF as micromega.GFormula.IFF.
+ Register EQ as micromega.GFormula.EQ.
Section MAPX.
- Variable F : TX -> TX.
+ Variable F : forall k, TX k -> TX k.
- Fixpoint mapX (f : GFormula) : GFormula :=
+ Fixpoint mapX (k:kind) (f : GFormula k) : GFormula k :=
match f with
- | TT => TT
- | FF => FF
- | X x => X (F x)
- | A a an => A a an
- | Cj f1 f2 => Cj (mapX f1) (mapX f2)
- | D f1 f2 => D (mapX f1) (mapX f2)
- | N f => N (mapX f)
- | I f1 o f2 => I (mapX f1) o (mapX f2)
+ | TT k => TT k
+ | FF k => FF k
+ | X x => X (F x)
+ | A k a an => A k a an
+ | AND f1 f2 => AND (mapX f1) (mapX f2)
+ | OR f1 f2 => OR (mapX f1) (mapX f2)
+ | NOT f => NOT (mapX f)
+ | IMPL f1 o f2 => IMPL (mapX f1) o (mapX f2)
+ | IFF f1 f2 => IFF (mapX f1) (mapX f2)
+ | EQ f1 f2 => EQ (mapX f1) (mapX f2)
end.
End MAPX.
@@ -68,16 +83,17 @@ Section S.
Variable ACC : Type.
Variable F : ACC -> AA -> ACC.
- Fixpoint foldA (f : GFormula) (acc : ACC) : ACC :=
+ Fixpoint foldA (k: kind) (f : GFormula k) (acc : ACC) : ACC :=
match f with
- | TT => acc
- | FF => acc
+ | TT _ => acc
+ | FF _ => acc
| X x => acc
- | A a an => F acc an
- | Cj f1 f2
- | D f1 f2
- | I f1 _ f2 => foldA f1 (foldA f2 acc)
- | N f => foldA f acc
+ | A _ a an => F acc an
+ | AND f1 f2
+ | OR f1 f2
+ | IFF f1 f2
+ | IMPL f1 _ f2 | EQ f1 f2 => foldA f1 (foldA f2 acc)
+ | NOT f => foldA f acc
end.
End FOLDANNOT.
@@ -89,84 +105,212 @@ Section S.
| Some id => id :: l
end.
- Fixpoint ids_of_formula f :=
+ Fixpoint ids_of_formula (k: kind) (f:GFormula k) :=
match f with
- | I f id f' => cons_id id (ids_of_formula f')
+ | IMPL f id f' => cons_id id (ids_of_formula f')
| _ => nil
end.
- Fixpoint collect_annot (f : GFormula) : list AA :=
+ Fixpoint collect_annot (k: kind) (f : GFormula k) : list AA :=
match f with
- | TT | FF | X _ => nil
- | A _ a => a ::nil
- | Cj f1 f2
- | D f1 f2
- | I f1 _ f2 => collect_annot f1 ++ collect_annot f2
- | N f => collect_annot f
+ | TT _ | FF _ | X _ => nil
+ | A _ _ a => a ::nil
+ | AND f1 f2
+ | OR f1 f2
+ | IFF f1 f2 | EQ f1 f2
+ | IMPL f1 _ f2 => collect_annot f1 ++ collect_annot f2
+ | NOT f => collect_annot f
end.
- Variable ex : TX -> Prop. (* [ex] will be the identity *)
+ Definition rtyp (k: kind) : Type := if k then Prop else bool.
- Section EVAL.
+ Variable ex : forall (k: kind), TX k -> rtyp k. (* [ex] will be the identity *)
- Variable ea : TA -> Prop.
+ Section EVAL.
- Fixpoint eval_f (f:GFormula) {struct f}: Prop :=
- match f with
- | TT => True
- | FF => False
- | A a _ => ea a
- | X p => ex p
- | Cj e1 e2 => (eval_f e1) /\ (eval_f e2)
- | D e1 e2 => (eval_f e1) \/ (eval_f e2)
- | N e => ~ (eval_f e)
- | I f1 _ f2 => (eval_f f1) -> (eval_f f2)
- end.
+ Variable ea : forall (k: kind), TA -> rtyp k.
+
+ Definition eTT (k: kind) : rtyp k :=
+ if k as k' return rtyp k' then True else true.
+
+ Definition eFF (k: kind) : rtyp k :=
+ if k as k' return rtyp k' then False else false.
+
+ Definition eAND (k: kind) : rtyp k -> rtyp k -> rtyp k :=
+ if k as k' return rtyp k' -> rtyp k' -> rtyp k'
+ then and else andb.
+
+ Definition eOR (k: kind) : rtyp k -> rtyp k -> rtyp k :=
+ if k as k' return rtyp k' -> rtyp k' -> rtyp k'
+ then or else orb.
+
+ Definition eIMPL (k: kind) : rtyp k -> rtyp k -> rtyp k :=
+ if k as k' return rtyp k' -> rtyp k' -> rtyp k'
+ then (fun x y => x -> y) else implb.
+
+ Definition eIFF (k: kind) : rtyp k -> rtyp k -> rtyp k :=
+ if k as k' return rtyp k' -> rtyp k' -> rtyp k'
+ then iff else eqb.
+
+ Definition eNOT (k: kind) : rtyp k -> rtyp k :=
+ if k as k' return rtyp k' -> rtyp k'
+ then not else negb.
+
+ Fixpoint eval_f (k: kind) (f:GFormula k) {struct f}: rtyp k :=
+ match f in GFormula k' return rtyp k' with
+ | TT tk => eTT tk
+ | FF tk => eFF tk
+ | A k a _ => ea k a
+ | X p => ex p
+ | @AND k e1 e2 => eAND k (eval_f e1) (eval_f e2)
+ | @OR k e1 e2 => eOR k (eval_f e1) (eval_f e2)
+ | @NOT k e => eNOT k (eval_f e)
+ | @IMPL k f1 _ f2 => eIMPL k (eval_f f1) (eval_f f2)
+ | @IFF k f1 f2 => eIFF k (eval_f f1) (eval_f f2)
+ | EQ f1 f2 => (eval_f f1) = (eval_f f2)
+ end.
+ Lemma eval_f_rew : forall k (f:GFormula k),
+ eval_f f =
+ match f in GFormula k' return rtyp k' with
+ | TT tk => eTT tk
+ | FF tk => eFF tk
+ | A k a _ => ea k a
+ | X p => ex p
+ | @AND k e1 e2 => eAND k (eval_f e1) (eval_f e2)
+ | @OR k e1 e2 => eOR k (eval_f e1) (eval_f e2)
+ | @NOT k e => eNOT k (eval_f e)
+ | @IMPL k f1 _ f2 => eIMPL k (eval_f f1) (eval_f f2)
+ | @IFF k f1 f2 => eIFF k (eval_f f1) (eval_f f2)
+ | EQ f1 f2 => (eval_f f1) = (eval_f f2)
+ end.
+ Proof.
+ destruct f ; reflexivity.
+ Qed.
End EVAL.
+ Definition hold (k: kind) : rtyp k -> Prop :=
+ if k as k0 return (rtyp k0 -> Prop) then fun x => x else is_true.
+ Definition eiff (k: kind) : rtyp k -> rtyp k -> Prop :=
+ if k as k' return rtyp k' -> rtyp k' -> Prop then iff else @eq bool.
+ Lemma eiff_refl : forall (k: kind) (x : rtyp k),
+ eiff k x x.
+ Proof.
+ destruct k ; simpl; tauto.
+ Qed.
- Lemma eval_f_morph :
- forall (ev ev' : TA -> Prop) (f : GFormula),
- (forall a, ev a <-> ev' a) -> (eval_f ev f <-> eval_f ev' f).
+ Lemma eiff_sym : forall k (x y : rtyp k), eiff k x y -> eiff k y x.
+ Proof.
+ destruct k ; simpl; intros ; intuition.
+ Qed.
+
+ Lemma eiff_trans : forall k (x y z : rtyp k), eiff k x y -> eiff k y z -> eiff k x z.
+ Proof.
+ destruct k ; simpl; intros ; intuition congruence.
+ Qed.
+
+ Lemma hold_eiff : forall (k: kind) (x y : rtyp k),
+ (hold k x <-> hold k y) <-> eiff k x y.
+ Proof.
+ destruct k ; simpl.
+ - tauto.
+ - unfold is_true.
+ destruct x,y ; intuition congruence.
+ Qed.
+
+ Instance eiff_eq (k: kind) : Equivalence (eiff k).
+ Proof.
+ constructor.
+ - exact (eiff_refl k).
+ - exact (eiff_sym k).
+ - exact (eiff_trans k).
+ Qed.
+
+ Add Parametric Morphism (k: kind) : (@eAND k) with signature eiff k ==> eiff k ==> eiff k as eAnd_morph.
+ Proof.
+ intros.
+ destruct k ; simpl in *; intuition congruence.
+ Qed.
+
+ Add Parametric Morphism (k: kind) : (@eOR k) with signature eiff k ==> eiff k ==> eiff k as eOR_morph.
+ Proof.
+ intros.
+ destruct k ; simpl in *; intuition congruence.
+ Qed.
+
+ Add Parametric Morphism (k: kind) : (@eIMPL k) with signature eiff k ==> eiff k ==> eiff k as eIMPL_morph.
+ Proof.
+ intros.
+ destruct k ; simpl in *; intuition congruence.
+ Qed.
+
+ Add Parametric Morphism (k: kind) : (@eIFF k) with signature eiff k ==> eiff k ==> eiff k as eIFF_morph.
Proof.
- induction f ; simpl ; try tauto.
intros.
- apply H.
+ destruct k ; simpl in *; intuition congruence.
Qed.
+ Add Parametric Morphism (k: kind) : (@eNOT k) with signature eiff k ==> eiff k as eNOT_morph.
+ Proof.
+ intros.
+ destruct k ; simpl in *; intuition congruence.
+ Qed.
+
+ Lemma eval_f_morph :
+ forall (ev ev' : forall (k: kind), TA -> rtyp k),
+ (forall k a, eiff k (ev k a) (ev' k a)) ->
+ forall (k: kind)(f : GFormula k),
+ (eiff k (eval_f ev f) (eval_f ev' f)).
+ Proof.
+ induction f ; simpl.
+ - reflexivity.
+ - reflexivity.
+ - reflexivity.
+ - apply H.
+ - rewrite IHf1. rewrite IHf2. reflexivity.
+ - rewrite IHf1. rewrite IHf2. reflexivity.
+ - rewrite IHf. reflexivity.
+ - rewrite IHf1. rewrite IHf2. reflexivity.
+ - rewrite IHf1. rewrite IHf2. reflexivity.
+ - simpl in *. intuition congruence.
+ Qed.
End S.
(** Typical boolean formulae *)
-Definition BFormula (A : Type) := @GFormula A Prop unit unit.
+Definition eKind (k: kind) := if k then Prop else bool.
+Register eKind as micromega.eKind.
+
+Definition BFormula (A : Type) := @GFormula A eKind unit unit.
Register BFormula as micromega.BFormula.type.
Section MAPATOMS.
Context {TA TA':Type}.
- Context {TX : Type}.
+ Context {TX : kind -> Type}.
Context {AA : Type}.
Context {AF : Type}.
-Fixpoint map_bformula (fct : TA -> TA') (f : @GFormula TA TX AA AF ) : @GFormula TA' TX AA AF :=
- match f with
- | TT => TT
- | FF => FF
- | X p => X p
- | A a t => A (fct a) t
- | Cj f1 f2 => Cj (map_bformula fct f1) (map_bformula fct f2)
- | D f1 f2 => D (map_bformula fct f1) (map_bformula fct f2)
- | N f => N (map_bformula fct f)
- | I f1 a f2 => I (map_bformula fct f1) a (map_bformula fct f2)
- end.
+ Fixpoint map_bformula (k: kind)(fct : TA -> TA') (f : @GFormula TA TX AA AF k) : @GFormula TA' TX AA AF k:=
+ match f with
+ | TT k => TT k
+ | FF k => FF k
+ | X k p => X k p
+ | A k a t => A k (fct a) t
+ | AND f1 f2 => AND (map_bformula fct f1) (map_bformula fct f2)
+ | OR f1 f2 => OR (map_bformula fct f1) (map_bformula fct f2)
+ | NOT f => NOT (map_bformula fct f)
+ | IMPL f1 a f2 => IMPL (map_bformula fct f1) a (map_bformula fct f2)
+ | IFF f1 f2 => IFF (map_bformula fct f1) (map_bformula fct f2)
+ | EQ f1 f2 => EQ (map_bformula fct f1) (map_bformula fct f2)
+ end.
End MAPATOMS.
@@ -204,345 +348,458 @@ Section S.
(** Our cnf is optimised and detects contradictions on the fly. *)
Fixpoint add_term (t: Term' * Annot) (cl : clause) : option clause :=
- match cl with
- | nil =>
- match deduce (fst t) (fst t) with
- | None => Some (t ::nil)
- | Some u => if unsat u then None else Some (t::nil)
+ match cl with
+ | nil =>
+ match deduce (fst t) (fst t) with
+ | None => Some (t ::nil)
+ | Some u => if unsat u then None else Some (t::nil)
+ end
+ | t'::cl =>
+ match deduce (fst t) (fst t') with
+ | None =>
+ match add_term t cl with
+ | None => None
+ | Some cl' => Some (t' :: cl')
end
- | t'::cl =>
- match deduce (fst t) (fst t') with
- | None =>
+ | Some u =>
+ if unsat u then None else
match add_term t cl with
| None => None
| Some cl' => Some (t' :: cl')
end
- | Some u =>
- if unsat u then None else
- match add_term t cl with
- | None => None
- | Some cl' => Some (t' :: cl')
- end
+ end
+ end.
+
+ Fixpoint or_clause (cl1 cl2 : clause) : option clause :=
+ match cl1 with
+ | nil => Some cl2
+ | t::cl => match add_term t cl2 with
+ | None => None
+ | Some cl' => or_clause cl cl'
+ end
+ end.
+
+ Definition xor_clause_cnf (t:clause) (f:cnf) : cnf :=
+ List.fold_left (fun acc e =>
+ match or_clause t e with
+ | None => acc
+ | Some cl => cl :: acc
+ end) f nil .
+
+ Definition or_clause_cnf (t: clause) (f:cnf) : cnf :=
+ match t with
+ | nil => f
+ | _ => xor_clause_cnf t f
+ end.
+
+
+ Fixpoint or_cnf (f : cnf) (f' : cnf) {struct f}: cnf :=
+ match f with
+ | nil => cnf_tt
+ | e :: rst => (or_cnf rst f') +++ (or_clause_cnf e f')
+ end.
+
+
+ Definition and_cnf (f1 : cnf) (f2 : cnf) : cnf :=
+ f1 +++ f2.
+
+ (** TX is Prop in Coq and EConstr.constr in Ocaml.
+ AF is unit in Coq and Names.Id.t in Ocaml
+ *)
+ Definition TFormula (TX: kind -> Type) (AF: Type) := @GFormula Term TX Annot AF.
+
+
+ Definition is_cnf_tt (c : cnf) : bool :=
+ match c with
+ | nil => true
+ | _ => false
+ end.
+
+ Definition is_cnf_ff (c : cnf) : bool :=
+ match c with
+ | nil::nil => true
+ | _ => false
+ end.
+
+ Definition and_cnf_opt (f1 : cnf) (f2 : cnf) : cnf :=
+ if is_cnf_ff f1 || is_cnf_ff f2
+ then cnf_ff
+ else
+ if is_cnf_tt f2
+ then f1
+ else and_cnf f1 f2.
+
+
+ Definition or_cnf_opt (f1 : cnf) (f2 : cnf) : cnf :=
+ if is_cnf_tt f1 || is_cnf_tt f2
+ then cnf_tt
+ else if is_cnf_ff f2
+ then f1 else or_cnf f1 f2.
+
+ Section REC.
+ Context {TX : kind -> Type}.
+ Context {AF : Type}.
+
+ Variable REC : forall (pol : bool) (k: kind) (f : TFormula TX AF k), cnf.
+
+ Definition mk_and (k: kind) (pol:bool) (f1 f2 : TFormula TX AF k):=
+ (if pol then and_cnf_opt else or_cnf_opt) (REC pol f1) (REC pol f2).
+
+ Definition mk_or (k: kind) (pol:bool) (f1 f2 : TFormula TX AF k):=
+ (if pol then or_cnf_opt else and_cnf_opt) (REC pol f1) (REC pol f2).
+
+ Definition mk_impl (k: kind) (pol:bool) (f1 f2 : TFormula TX AF k):=
+ (if pol then or_cnf_opt else and_cnf_opt) (REC (negb pol) f1) (REC pol f2).
+
+
+ Definition mk_iff (k: kind) (pol:bool) (f1 f2: TFormula TX AF k):=
+ or_cnf_opt (and_cnf_opt (REC (negb pol) f1) (REC false f2))
+ (and_cnf_opt (REC pol f1) (REC true f2)).
+
+
+ End REC.
+
+ Definition is_bool {TX : kind -> Type} {AF: Type} (k: kind) (f : TFormula TX AF k) :=
+ match f with
+ | TT _ => Some true
+ | FF _ => Some false
+ | _ => None
+ end.
+
+ Lemma is_bool_inv : forall {TX : kind -> Type} {AF: Type} (k: kind) (f : TFormula TX AF k) res,
+ is_bool f = Some res -> f = if res then TT _ else FF _.
+ Proof.
+ intros.
+ destruct f ; inversion H; reflexivity.
+ Qed.
+
+
+ Fixpoint xcnf {TX : kind -> Type} {AF: Type} (pol : bool) (k: kind) (f : TFormula TX AF k) {struct f}: cnf :=
+ match f with
+ | TT _ => if pol then cnf_tt else cnf_ff
+ | FF _ => if pol then cnf_ff else cnf_tt
+ | X _ p => if pol then cnf_ff else cnf_ff (* This is not complete - cannot negate any proposition *)
+ | A _ x t => if pol then normalise x t else negate x t
+ | NOT e => xcnf (negb pol) e
+ | AND e1 e2 => mk_and xcnf pol e1 e2
+ | OR e1 e2 => mk_or xcnf pol e1 e2
+ | IMPL e1 _ e2 => mk_impl xcnf pol e1 e2
+ | IFF e1 e2 => match is_bool e2 with
+ | Some isb => xcnf (if isb then pol else negb pol) e1
+ | None => mk_iff xcnf pol e1 e2
+ end
+ | EQ e1 e2 =>
+ match is_bool e2 with
+ | Some isb => xcnf (if isb then pol else negb pol) e1
+ | None => mk_iff xcnf pol e1 e2
+ end
+ end.
+
+ Section CNFAnnot.
+
+ (** Records annotations used to optimise the cnf.
+ Those need to be kept when pruning the formula.
+ For efficiency, this is a separate function.
+ *)
+
+ Fixpoint radd_term (t : Term' * Annot) (cl : clause) : clause + list Annot :=
+ match cl with
+ | nil => (* if t is unsat, the clause is empty BUT t is needed. *)
+ match deduce (fst t) (fst t) with
+ | Some u => if unsat u then inr ((snd t)::nil) else inl (t::nil)
+ | None => inl (t::nil)
+ end
+ | t'::cl => (* if t /\ t' is unsat, the clause is empty BUT t & t' are needed *)
+ match deduce (fst t) (fst t') with
+ | Some u => if unsat u then inr ((snd t)::(snd t')::nil)
+ else match radd_term t cl with
+ | inl cl' => inl (t'::cl')
+ | inr l => inr l
+ end
+ | None => match radd_term t cl with
+ | inl cl' => inl (t'::cl')
+ | inr l => inr l
+ end
end
end.
- Fixpoint or_clause (cl1 cl2 : clause) : option clause :=
+ Fixpoint ror_clause cl1 cl2 :=
match cl1 with
- | nil => Some cl2
- | t::cl => match add_term t cl2 with
- | None => None
- | Some cl' => or_clause cl cl'
+ | nil => inl cl2
+ | t::cl => match radd_term t cl2 with
+ | inl cl' => ror_clause cl cl'
+ | inr l => inr l
end
end.
- Definition xor_clause_cnf (t:clause) (f:cnf) : cnf :=
- List.fold_left (fun acc e =>
- match or_clause t e with
- | None => acc
- | Some cl => cl :: acc
- end) f nil .
+ Definition xror_clause_cnf t f :=
+ List.fold_left (fun '(acc,tg) e =>
+ match ror_clause t e with
+ | inl cl => (cl :: acc,tg)
+ | inr l => (acc,tg+++l)
+ end) f (nil,nil).
- Definition or_clause_cnf (t: clause) (f:cnf) : cnf :=
+ Definition ror_clause_cnf t f :=
match t with
- | nil => f
- | _ => xor_clause_cnf t f
+ | nil => (f,nil)
+ | _ => xror_clause_cnf t f
end.
- Fixpoint or_cnf (f : cnf) (f' : cnf) {struct f}: cnf :=
+ Fixpoint ror_cnf (f f':list clause) :=
match f with
- | nil => cnf_tt
- | e :: rst => (or_cnf rst f') +++ (or_clause_cnf e f')
+ | nil => (cnf_tt,nil)
+ | e :: rst =>
+ let (rst_f',t) := ror_cnf rst f' in
+ let (e_f', t') := ror_clause_cnf e f' in
+ (rst_f' +++ e_f', t +++ t')
end.
+ Definition annot_of_clause (l : clause) : list Annot :=
+ List.map snd l.
- Definition and_cnf (f1 : cnf) (f2 : cnf) : cnf :=
- f1 +++ f2.
+ Definition annot_of_cnf (f : cnf) : list Annot :=
+ List.fold_left (fun acc e => annot_of_clause e +++ acc ) f nil.
- (** TX is Prop in Coq and EConstr.constr in Ocaml.
- AF i s unit in Coq and Names.Id.t in Ocaml
- *)
- Definition TFormula (TX: Type) (AF: Type) := @GFormula Term TX Annot AF.
+ Definition ror_cnf_opt f1 f2 :=
+ if is_cnf_tt f1
+ then (cnf_tt , nil)
+ else if is_cnf_tt f2
+ then (cnf_tt, nil)
+ else if is_cnf_ff f2
+ then (f1,nil)
+ else ror_cnf f1 f2.
- Definition is_cnf_tt (c : cnf) : bool :=
- match c with
- | nil => true
- | _ => false
- end.
- Definition is_cnf_ff (c : cnf) : bool :=
- match c with
- | nil::nil => true
- | _ => false
+ Definition ocons {A : Type} (o : option A) (l : list A) : list A :=
+ match o with
+ | None => l
+ | Some e => e ::l
end.
- Definition and_cnf_opt (f1 : cnf) (f2 : cnf) : cnf :=
- if is_cnf_ff f1 || is_cnf_ff f2
- then cnf_ff
- else and_cnf f1 f2.
-
- Definition or_cnf_opt (f1 : cnf) (f2 : cnf) : cnf :=
- if is_cnf_tt f1 || is_cnf_tt f2
- then cnf_tt
- else if is_cnf_ff f2
- then f1 else or_cnf f1 f2.
+ Definition ratom (c : cnf) (a : Annot) : cnf * list Annot :=
+ if is_cnf_ff c || is_cnf_tt c
+ then (c,a::nil)
+ else (c,nil). (* t is embedded in c *)
+
+ Section REC.
+ Context {TX : kind -> Type} {AF : Type}.
+
+ Variable RXCNF : forall (polarity: bool) (k: kind) (f: TFormula TX AF k) , cnf * list Annot.
+
+ Definition rxcnf_and (polarity:bool) (k: kind) (e1 e2 : TFormula TX AF k) :=
+ let '(e1,t1) := RXCNF polarity e1 in
+ let '(e2,t2) := RXCNF polarity e2 in
+ if polarity
+ then (and_cnf_opt e1 e2, t1 +++ t2)
+ else let (f',t') := ror_cnf_opt e1 e2 in
+ (f', t1 +++ t2 +++ t').
+
+ Definition rxcnf_or (polarity:bool) (k: kind) (e1 e2 : TFormula TX AF k) :=
+ let '(e1,t1) := RXCNF polarity e1 in
+ let '(e2,t2) := RXCNF polarity e2 in
+ if polarity
+ then let (f',t') := ror_cnf_opt e1 e2 in
+ (f', t1 +++ t2 +++ t')
+ else (and_cnf_opt e1 e2, t1 +++ t2).
+
+ Definition rxcnf_impl (polarity:bool) (k: kind) (e1 e2 : TFormula TX AF k) :=
+ let '(e1 , t1) := (RXCNF (negb polarity) e1) in
+ if polarity
+ then
+ if is_cnf_ff e1
+ then
+ RXCNF polarity e2
+ else (* compute disjunction *)
+ let '(e2 , t2) := (RXCNF polarity e2) in
+ let (f',t') := ror_cnf_opt e1 e2 in
+ (f', t1 +++ t2 +++ t') (* record the hypothesis *)
+ else
+ let '(e2 , t2) := (RXCNF polarity e2) in
+ (and_cnf_opt e1 e2, t1 +++ t2).
+
+ Definition rxcnf_iff (polarity:bool) (k: kind) (e1 e2 : TFormula TX AF k) :=
+ let '(c1,t1) := RXCNF (negb polarity) e1 in
+ let '(c2,t2) := RXCNF false e2 in
+ let '(c3,t3) := RXCNF polarity e1 in
+ let '(c4,t4) := RXCNF true e2 in
+ let (f',t') := ror_cnf_opt (and_cnf_opt c1 c2) (and_cnf_opt c3 c4) in
+ (f', t1+++ t2+++t3 +++ t4 +++ t')
+ .
+
+ End REC.
+
+ Fixpoint rxcnf {TX : kind -> Type} {AF: Type}(polarity : bool) (k: kind) (f : TFormula TX AF k) : cnf * list Annot :=
- Fixpoint xcnf {TX AF: Type} (pol : bool) (f : TFormula TX AF) {struct f}: cnf :=
match f with
- | TT => if pol then cnf_tt else cnf_ff
- | FF => if pol then cnf_ff else cnf_tt
- | X p => if pol then cnf_ff else cnf_ff (* This is not complete - cannot negate any proposition *)
- | A x t => if pol then normalise x t else negate x t
- | N e => xcnf (negb pol) e
- | Cj e1 e2 =>
- (if pol then and_cnf_opt else or_cnf_opt) (xcnf pol e1) (xcnf pol e2)
- | D e1 e2 => (if pol then or_cnf_opt else and_cnf_opt) (xcnf pol e1) (xcnf pol e2)
- | I e1 _ e2
- => (if pol then or_cnf_opt else and_cnf_opt) (xcnf (negb pol) e1) (xcnf pol e2)
+ | TT _ => if polarity then (cnf_tt,nil) else (cnf_ff,nil)
+ | FF _ => if polarity then (cnf_ff,nil) else (cnf_tt,nil)
+ | X b p => if polarity then (cnf_ff,nil) else (cnf_ff,nil)
+ | A _ x t => ratom (if polarity then normalise x t else negate x t) t
+ | NOT e => rxcnf (negb polarity) e
+ | AND e1 e2 => rxcnf_and rxcnf polarity e1 e2
+ | OR e1 e2 => rxcnf_or rxcnf polarity e1 e2
+ | IMPL e1 a e2 => rxcnf_impl rxcnf polarity e1 e2
+ | IFF e1 e2 => rxcnf_iff rxcnf polarity e1 e2
+ | EQ e1 e2 => rxcnf_iff rxcnf polarity e1 e2
end.
- Section CNFAnnot.
-
- (** Records annotations used to optimise the cnf.
- Those need to be kept when pruning the formula.
- For efficiency, this is a separate function.
- *)
-
- Fixpoint radd_term (t : Term' * Annot) (cl : clause) : clause + list Annot :=
- match cl with
- | nil => (* if t is unsat, the clause is empty BUT t is needed. *)
- match deduce (fst t) (fst t) with
- | Some u => if unsat u then inr ((snd t)::nil) else inl (t::nil)
- | None => inl (t::nil)
- end
- | t'::cl => (* if t /\ t' is unsat, the clause is empty BUT t & t' are needed *)
- match deduce (fst t) (fst t') with
- | Some u => if unsat u then inr ((snd t)::(snd t')::nil)
- else match radd_term t cl with
- | inl cl' => inl (t'::cl')
- | inr l => inr l
- end
- | None => match radd_term t cl with
- | inl cl' => inl (t'::cl')
- | inr l => inr l
- end
- end
- end.
+ Section Abstraction.
+ Variable TX : kind -> Type.
+ Variable AF : Type.
- Fixpoint ror_clause cl1 cl2 :=
- match cl1 with
- | nil => inl cl2
- | t::cl => match radd_term t cl2 with
- | inl cl' => ror_clause cl cl'
- | inr l => inr l
- end
- end.
+ Class to_constrT : Type :=
+ {
+ mkTT : forall (k: kind), TX k;
+ mkFF : forall (k: kind), TX k;
+ mkA : forall (k: kind), Term -> Annot -> TX k;
+ mkAND : forall (k: kind), TX k -> TX k -> TX k;
+ mkOR : forall (k: kind), TX k -> TX k -> TX k;
+ mkIMPL : forall (k: kind), TX k -> TX k -> TX k;
+ mkIFF : forall (k: kind), TX k -> TX k -> TX k;
+ mkNOT : forall (k: kind), TX k -> TX k;
+ mkEQ : TX isBool -> TX isBool -> TX isProp
- Definition xror_clause_cnf t f :=
- List.fold_left (fun '(acc,tg) e =>
- match ror_clause t e with
- | inl cl => (cl :: acc,tg)
- | inr l => (acc,tg+++l)
- end) f (nil,nil).
-
- Definition ror_clause_cnf t f :=
- match t with
- | nil => (f,nil)
- | _ => xror_clause_cnf t f
- end.
+ }.
+ Context {to_constr : to_constrT}.
- Fixpoint ror_cnf (f f':list clause) :=
+ Fixpoint aformula (k: kind) (f : TFormula TX AF k) : TX k :=
match f with
- | nil => (cnf_tt,nil)
- | e :: rst =>
- let (rst_f',t) := ror_cnf rst f' in
- let (e_f', t') := ror_clause_cnf e f' in
- (rst_f' +++ e_f', t +++ t')
+ | TT b => mkTT b
+ | FF b => mkFF b
+ | X b p => p
+ | A b x t => mkA b x t
+ | AND f1 f2 => mkAND (aformula f1) (aformula f2)
+ | OR f1 f2 => mkOR (aformula f1) (aformula f2)
+ | IMPL f1 o f2 => mkIMPL (aformula f1) (aformula f2)
+ | IFF f1 f2 => mkIFF (aformula f1) (aformula f2)
+ | NOT f => mkNOT (aformula f)
+ | EQ f1 f2 => mkEQ (aformula f1) (aformula f2)
end.
- Definition annot_of_clause (l : clause) : list Annot :=
- List.map snd l.
-
- Definition annot_of_cnf (f : cnf) : list Annot :=
- List.fold_left (fun acc e => annot_of_clause e +++ acc ) f nil.
+ Definition is_X (k: kind) (f : TFormula TX AF k) : option (TX k) :=
+ match f with
+ | X _ p => Some p
+ | _ => None
+ end.
- Definition ror_cnf_opt f1 f2 :=
- if is_cnf_tt f1
- then (cnf_tt , nil)
- else if is_cnf_tt f2
- then (cnf_tt, nil)
- else if is_cnf_ff f2
- then (f1,nil)
- else ror_cnf f1 f2.
+ Definition is_X_inv : forall (k: kind) (f: TFormula TX AF k) x,
+ is_X f = Some x -> f = X k x.
+ Proof.
+ destruct f ; simpl ; try congruence.
+ Qed.
+ Variable needA : Annot -> bool.
- Definition ocons {A : Type} (o : option A) (l : list A) : list A :=
- match o with
- | None => l
- | Some e => e ::l
+ Definition abs_and (k: kind) (f1 f2 : TFormula TX AF k)
+ (c : forall (k: kind), TFormula TX AF k -> TFormula TX AF k -> TFormula TX AF k) :=
+ match is_X f1 , is_X f2 with
+ | Some _ , _ | _ , Some _ => X k (aformula (c k f1 f2))
+ | _ , _ => c k f1 f2
end.
- Definition ratom (c : cnf) (a : Annot) : cnf * list Annot :=
- if is_cnf_ff c || is_cnf_tt c
- then (c,a::nil)
- else (c,nil). (* t is embedded in c *)
-
- Fixpoint rxcnf {TX AF: Type}(polarity : bool) (f : TFormula TX AF) : cnf * list Annot :=
- match f with
- | TT => if polarity then (cnf_tt,nil) else (cnf_ff,nil)
- | FF => if polarity then (cnf_ff,nil) else (cnf_tt,nil)
- | X p => if polarity then (cnf_ff,nil) else (cnf_ff,nil)
- | A x t => ratom (if polarity then normalise x t else negate x t) t
- | N e => rxcnf (negb polarity) e
- | Cj e1 e2 =>
- let '(e1,t1) := rxcnf polarity e1 in
- let '(e2,t2) := rxcnf polarity e2 in
- if polarity
- then (and_cnf_opt e1 e2, t1 +++ t2)
- else let (f',t') := ror_cnf_opt e1 e2 in
- (f', t1 +++ t2 +++ t')
- | D e1 e2 =>
- let '(e1,t1) := rxcnf polarity e1 in
- let '(e2,t2) := rxcnf polarity e2 in
- if polarity
- then let (f',t') := ror_cnf_opt e1 e2 in
- (f', t1 +++ t2 +++ t')
- else (and_cnf_opt e1 e2, t1 +++ t2)
- | I e1 a e2 =>
- let '(e1 , t1) := (rxcnf (negb polarity) e1) in
- if polarity
- then
- if is_cnf_ff e1
- then
- rxcnf polarity e2
- else (* compute disjunction *)
- let '(e2 , t2) := (rxcnf polarity e2) in
- let (f',t') := ror_cnf_opt e1 e2 in
- (f', t1 +++ t2 +++ t') (* record the hypothesis *)
- else
- let '(e2 , t2) := (rxcnf polarity e2) in
- (and_cnf_opt e1 e2, t1 +++ t2)
+ Definition abs_or (k: kind) (f1 f2 : TFormula TX AF k)
+ (c : forall (k: kind), TFormula TX AF k -> TFormula TX AF k -> TFormula TX AF k) :=
+ match is_X f1 , is_X f2 with
+ | Some _ , Some _ => X k (aformula (c k f1 f2))
+ | _ , _ => c k f1 f2
end.
+ Definition abs_not (k: kind) (f1 : TFormula TX AF k)
+ (c : forall (k: kind), TFormula TX AF k -> TFormula TX AF k) :=
+ match is_X f1 with
+ | Some _ => X k (aformula (c k f1 ))
+ | _ => c k f1
+ end.
- Section Abstraction.
- Variable TX : Type.
- Variable AF : Type.
-
- Class to_constrT : Type :=
- {
- mkTT : TX;
- mkFF : TX;
- mkA : Term -> Annot -> TX;
- mkCj : TX -> TX -> TX;
- mkD : TX -> TX -> TX;
- mkI : TX -> TX -> TX;
- mkN : TX -> TX
- }.
-
- Context {to_constr : to_constrT}.
-
- Fixpoint aformula (f : TFormula TX AF) : TX :=
- match f with
- | TT => mkTT
- | FF => mkFF
- | X p => p
- | A x t => mkA x t
- | Cj f1 f2 => mkCj (aformula f1) (aformula f2)
- | D f1 f2 => mkD (aformula f1) (aformula f2)
- | I f1 o f2 => mkI (aformula f1) (aformula f2)
- | N f => mkN (aformula f)
- end.
+ Definition mk_arrow (o : option AF) (k: kind) (f1 f2: TFormula TX AF k) :=
+ match o with
+ | None => IMPL f1 None f2
+ | Some _ => if is_X f1 then f2 else IMPL f1 o f2
+ end.
- Definition is_X (f : TFormula TX AF) : option TX :=
- match f with
- | X p => Some p
- | _ => None
- end.
+ Fixpoint abst_simpl (k: kind) (f : TFormula TX AF k) : TFormula TX AF k:=
+ match f with
+ | TT k => TT k
+ | FF k => FF k
+ | X k p => X k p
+ | A k x t => if needA t then A k x t else X k (mkA k x t)
+ | AND f1 f2 => AND (abst_simpl f1) (abst_simpl f2)
+ | OR f1 f2 => OR (abst_simpl f1) (abst_simpl f2)
+ | IMPL f1 o f2 => IMPL (abst_simpl f1) o (abst_simpl f2)
+ | NOT f => NOT (abst_simpl f)
+ | IFF f1 f2 => IFF (abst_simpl f1) (abst_simpl f2)
+ | EQ f1 f2 => EQ (abst_simpl f1) (abst_simpl f2)
+ end.
- Definition is_X_inv : forall f x,
- is_X f = Some x -> f = X x.
- Proof.
- destruct f ; simpl ; congruence.
- Qed.
+ Section REC.
+ Variable REC : forall (pol : bool) (k: kind) (f : TFormula TX AF k), TFormula TX AF k.
+ Definition abst_and (pol : bool) (k: kind) (f1 f2:TFormula TX AF k) : TFormula TX AF k:=
+ (if pol then abs_and else abs_or) k (REC pol f1) (REC pol f2) AND.
- Variable needA : Annot -> bool.
+ Definition abst_or (pol : bool) (k: kind) (f1 f2:TFormula TX AF k) : TFormula TX AF k:=
+ (if pol then abs_or else abs_and) k (REC pol f1) (REC pol f2) OR.
- Definition abs_and (f1 f2 : TFormula TX AF)
- (c : TFormula TX AF -> TFormula TX AF -> TFormula TX AF) :=
- match is_X f1 , is_X f2 with
- | Some _ , _ | _ , Some _ => X (aformula (c f1 f2))
- | _ , _ => c f1 f2
- end.
+ Definition abst_impl (pol : bool) (o :option AF) (k: kind) (f1 f2:TFormula TX AF k) : TFormula TX AF k:=
+ (if pol then abs_or else abs_and) k (REC (negb pol) f1) (REC pol f2) (mk_arrow o).
- Definition abs_or (f1 f2 : TFormula TX AF)
- (c : TFormula TX AF -> TFormula TX AF -> TFormula TX AF) :=
+ Definition or_is_X (k: kind) (f1 f2: TFormula TX AF k) : bool :=
match is_X f1 , is_X f2 with
- | Some _ , Some _ => X (aformula (c f1 f2))
- | _ , _ => c f1 f2
+ | Some _ , _
+ | _ , Some _ => true
+ | _ , _ => false
end.
- Definition mk_arrow (o : option AF) (f1 f2: TFormula TX AF) :=
- match o with
- | None => I f1 None f2
- | Some _ => if is_X f1 then f2 else I f1 o f2
- end.
+ Definition abs_iff (k: kind) (nf1 ff2 f1 tf2 : TFormula TX AF k) (r: kind) (def : TFormula TX AF r) : TFormula TX AF r :=
+ if andb (or_is_X nf1 ff2) (or_is_X f1 tf2)
+ then X r (aformula def)
+ else def.
- Fixpoint abst_form (pol : bool) (f : TFormula TX AF) :=
- match f with
- | TT => if pol then TT else X mkTT
- | FF => if pol then X mkFF else FF
- | X p => X p
- | A x t => if needA t then A x t else X (mkA x t)
- | Cj f1 f2 =>
- let f1 := abst_form pol f1 in
- let f2 := abst_form pol f2 in
- if pol then abs_and f1 f2 Cj
- else abs_or f1 f2 Cj
- | D f1 f2 =>
- let f1 := abst_form pol f1 in
- let f2 := abst_form pol f2 in
- if pol then abs_or f1 f2 D
- else abs_and f1 f2 D
- | I f1 o f2 =>
- let f1 := abst_form (negb pol) f1 in
- let f2 := abst_form pol f2 in
- if pol
- then abs_or f1 f2 (mk_arrow o)
- else abs_and f1 f2 (mk_arrow o)
- | N f => let f := abst_form (negb pol) f in
- match is_X f with
- | Some a => X (mkN a)
- | _ => N f
- end
- end.
+ Definition abst_iff (pol : bool) (k: kind) (f1 f2: TFormula TX AF k) : TFormula TX AF k :=
+ abs_iff (REC (negb pol) f1) (REC false f2) (REC pol f1) (REC true f2) (IFF (abst_simpl f1) (abst_simpl f2)).
+ Definition abst_eq (pol : bool) (f1 f2: TFormula TX AF isBool) : TFormula TX AF isProp :=
+ abs_iff (REC (negb pol) f1) (REC false f2) (REC pol f1) (REC true f2) (EQ (abst_simpl f1) (abst_simpl f2)).
+ End REC.
+ Fixpoint abst_form (pol : bool) (k: kind) (f : TFormula TX AF k) : TFormula TX AF k:=
+ match f with
+ | TT k => if pol then TT k else X k (mkTT k)
+ | FF k => if pol then X k (mkFF k) else FF k
+ | X k p => X k p
+ | A k x t => if needA t then A k x t else X k (mkA k x t)
+ | AND f1 f2 => abst_and abst_form pol f1 f2
+ | OR f1 f2 => abst_or abst_form pol f1 f2
+ | IMPL f1 o f2 => abst_impl abst_form pol o f1 f2
+ | NOT f => abs_not (abst_form (negb pol) f) NOT
+ | IFF f1 f2 => abst_iff abst_form pol f1 f2
+ | EQ f1 f2 => abst_eq abst_form pol f1 f2
+ end.
- Lemma if_same : forall {A: Type} (b:bool) (t:A),
- (if b then t else t) = t.
- Proof.
- destruct b ; reflexivity.
- Qed.
+ Lemma if_same : forall {A: Type} (b: bool) (t:A),
+ (if b then t else t) = t.
+ Proof.
+ destruct b ; reflexivity.
+ Qed.
- Lemma is_cnf_tt_cnf_ff :
- is_cnf_tt cnf_ff = false.
- Proof.
- reflexivity.
- Qed.
+ Lemma is_cnf_tt_cnf_ff :
+ is_cnf_tt cnf_ff = false.
+ Proof.
+ reflexivity.
+ Qed.
- Lemma is_cnf_ff_cnf_ff :
- is_cnf_ff cnf_ff = true.
- Proof.
- reflexivity.
- Qed.
+ Lemma is_cnf_ff_cnf_ff :
+ is_cnf_ff cnf_ff = true.
+ Proof.
+ reflexivity.
+ Qed.
Lemma is_cnf_tt_inv : forall f1,
@@ -587,9 +844,9 @@ Section S.
reflexivity.
Qed.
- Lemma abs_and_pol : forall f1 f2 pol,
+ Lemma abs_and_pol : forall (k: kind) (f1 f2: TFormula TX AF k) pol,
and_cnf_opt (xcnf pol f1) (xcnf pol f2) =
- xcnf pol (abs_and f1 f2 (if pol then Cj else D)).
+ xcnf pol (abs_and f1 f2 (if pol then AND else OR)).
Proof.
unfold abs_and; intros.
destruct (is_X f1) eqn:EQ1.
@@ -607,9 +864,9 @@ Section S.
destruct pol ; simpl; auto.
Qed.
- Lemma abs_or_pol : forall f1 f2 pol,
+ Lemma abs_or_pol : forall (k: kind) (f1 f2:TFormula TX AF k) pol,
or_cnf_opt (xcnf pol f1) (xcnf pol f2) =
- xcnf pol (abs_or f1 f2 (if pol then D else Cj)).
+ xcnf pol (abs_or f1 f2 (if pol then OR else AND)).
Proof.
unfold abs_or; intros.
destruct (is_X f1) eqn:EQ1.
@@ -629,8 +886,8 @@ Section S.
Variable needA_all : forall a, needA a = true.
- Lemma xcnf_true_mk_arrow_l : forall o t f,
- xcnf true (mk_arrow o (X t) f) = xcnf true f.
+ Lemma xcnf_true_mk_arrow_l : forall b o t (f:TFormula TX AF b),
+ xcnf true (mk_arrow o (X b t) f) = xcnf true f.
Proof.
destruct o ; simpl; auto.
intros. rewrite or_cnf_opt_cnf_ff. reflexivity.
@@ -647,8 +904,8 @@ Section S.
apply if_cnf_tt.
Qed.
- Lemma xcnf_true_mk_arrow_r : forall o t f,
- xcnf true (mk_arrow o f (X t)) = xcnf false f.
+ Lemma xcnf_true_mk_arrow_r : forall b o t (f:TFormula TX AF b),
+ xcnf true (mk_arrow o f (X b t)) = xcnf false f.
Proof.
destruct o ; simpl; auto.
- intros.
@@ -660,9 +917,167 @@ Section S.
apply or_cnf_opt_cnf_ff_r.
Qed.
+ Lemma and_cnf_opt_cnf_ff_r : forall f,
+ and_cnf_opt f cnf_ff = cnf_ff.
+ Proof.
+ intros.
+ unfold and_cnf_opt.
+ rewrite is_cnf_ff_cnf_ff.
+ rewrite orb_comm. reflexivity.
+ Qed.
+
+ Lemma and_cnf_opt_cnf_ff : forall f,
+ and_cnf_opt cnf_ff f = cnf_ff.
+ Proof.
+ intros.
+ unfold and_cnf_opt.
+ rewrite is_cnf_ff_cnf_ff.
+ reflexivity.
+ Qed.
+
+
+ Lemma and_cnf_opt_cnf_tt : forall f,
+ and_cnf_opt f cnf_tt = f.
+ Proof.
+ intros.
+ unfold and_cnf_opt.
+ simpl. rewrite orb_comm.
+ simpl.
+ destruct (is_cnf_ff f) eqn:EQ ; auto.
+ apply is_cnf_ff_inv in EQ.
+ auto.
+ Qed.
+
+ Lemma is_bool_abst_simpl : forall b (f:TFormula TX AF b),
+ is_bool (abst_simpl f) = is_bool f.
+ Proof.
+ induction f ; simpl ; auto.
+ rewrite needA_all.
+ reflexivity.
+ Qed.
+
+ Lemma abst_simpl_correct : forall b (f:TFormula TX AF b) pol,
+ xcnf pol f = xcnf pol (abst_simpl f).
+ Proof.
+ induction f; simpl;intros;
+ unfold mk_and,mk_or,mk_impl, mk_iff;
+ rewrite <- ?IHf;
+ try (rewrite <- !IHf1; rewrite <- !IHf2);
+ try reflexivity.
+ - rewrite needA_all.
+ reflexivity.
+ - rewrite is_bool_abst_simpl.
+ destruct (is_bool f2); auto.
+ - rewrite is_bool_abst_simpl.
+ destruct (is_bool f2); auto.
+ Qed.
+
+ Ltac is_X :=
+ match goal with
+ | |-context[is_X ?X] =>
+ let f := fresh "EQ" in
+ destruct (is_X X) eqn:f ;
+ [apply is_X_inv in f|]
+ end.
+
+ Ltac cnf_simpl :=
+ repeat match goal with
+ | |- context[and_cnf_opt cnf_ff _ ] => rewrite and_cnf_opt_cnf_ff
+ | |- context[and_cnf_opt _ cnf_ff] => rewrite and_cnf_opt_cnf_ff_r
+ | |- context[and_cnf_opt _ cnf_tt] => rewrite and_cnf_opt_cnf_tt
+ | |- context[or_cnf_opt cnf_ff _] => rewrite or_cnf_opt_cnf_ff
+ | |- context[or_cnf_opt _ cnf_ff] => rewrite or_cnf_opt_cnf_ff_r
+ end.
+
+ Lemma or_is_X_inv : forall (k: kind) (f1 f2 : TFormula TX AF k),
+ or_is_X f1 f2 = true ->
+ exists k1, is_X f1 = Some k1 \/ is_X f2 = Some k1.
+ Proof.
+ unfold or_is_X.
+ intros k f1 f2.
+ repeat is_X.
+ exists t ; intuition.
+ exists t ; intuition.
+ exists t ; intuition.
+ congruence.
+ Qed.
+
+ Lemma mk_iff_is_bool : forall (k: kind) (f1 f2:TFormula TX AF k) pol,
+ match is_bool f2 with
+ | Some isb => xcnf (if isb then pol else negb pol) f1
+ | None => mk_iff xcnf pol f1 f2
+ end = mk_iff xcnf pol f1 f2.
+ Proof.
+ intros.
+ destruct (is_bool f2) eqn:EQ; auto.
+ apply is_bool_inv in EQ.
+ subst.
+ unfold mk_iff.
+ destruct b ; simpl; cnf_simpl; reflexivity.
+ Qed.
+
+ Lemma abst_iff_correct : forall
+ (k: kind)
+ (f1 f2 : GFormula k)
+ (IHf1 : forall pol : bool, xcnf pol f1 = xcnf pol (abst_form pol f1))
+ (IHf2 : forall pol : bool, xcnf pol f2 = xcnf pol (abst_form pol f2))
+ (pol : bool),
+ xcnf pol (IFF f1 f2) = xcnf pol (abst_iff abst_form pol f1 f2).
+ Proof.
+ intros; simpl.
+ assert (D1 :mk_iff xcnf pol f1 f2 = mk_iff xcnf pol (abst_simpl f1) (abst_simpl f2)).
+ {
+ simpl.
+ unfold mk_iff.
+ rewrite <- !abst_simpl_correct.
+ reflexivity.
+ }
+ rewrite mk_iff_is_bool.
+ unfold abst_iff,abs_iff.
+ destruct ( or_is_X (abst_form (negb pol) f1) (abst_form false f2) &&
+ or_is_X (abst_form pol f1) (abst_form true f2)
+ ) eqn:EQ1.
+ + simpl.
+ rewrite andb_true_iff in EQ1.
+ destruct EQ1 as (EQ1 & EQ2).
+ apply or_is_X_inv in EQ1.
+ apply or_is_X_inv in EQ2.
+ destruct EQ1 as (b1 & EQ1).
+ destruct EQ2 as (b2 & EQ2).
+ rewrite if_same.
+ unfold mk_iff.
+ rewrite !IHf1.
+ rewrite !IHf2.
+ destruct EQ1 as [EQ1 | EQ1] ; apply is_X_inv in EQ1;
+ destruct EQ2 as [EQ2 | EQ2] ; apply is_X_inv in EQ2;
+ rewrite EQ1; rewrite EQ2; simpl;
+ repeat rewrite if_same ; cnf_simpl; auto.
+ + simpl.
+ rewrite mk_iff_is_bool.
+ unfold mk_iff.
+ rewrite <- ! abst_simpl_correct.
+ reflexivity.
+ Qed.
+
+ Lemma abst_eq_correct : forall
+ (f1 f2 : GFormula isBool)
+ (IHf1 : forall pol : bool, xcnf pol f1 = xcnf pol (abst_form pol f1))
+ (IHf2 : forall pol : bool, xcnf pol f2 = xcnf pol (abst_form pol f2))
+ (pol : bool),
+ xcnf pol (EQ f1 f2) = xcnf pol (abst_form pol (EQ f1 f2)).
+ Proof.
+ intros.
+ change (xcnf pol (IFF f1 f2) = xcnf pol (abst_form pol (EQ f1 f2))).
+ rewrite abst_iff_correct by assumption.
+ simpl. unfold abst_iff, abst_eq.
+ unfold abs_iff.
+ destruct (or_is_X (abst_form (negb pol) f1) (abst_form false f2) &&
+ or_is_X (abst_form pol f1) (abst_form true f2)
+ ) ; auto.
+ Qed.
- Lemma abst_form_correct : forall f pol,
+ Lemma abst_form_correct : forall b (f:TFormula TX AF b) pol,
xcnf pol f = xcnf pol (abst_form pol f).
Proof.
induction f;intros.
@@ -671,27 +1086,24 @@ Section S.
- simpl. reflexivity.
- simpl. rewrite needA_all.
reflexivity.
- - simpl.
+ - simpl. unfold mk_and.
specialize (IHf1 pol).
specialize (IHf2 pol).
rewrite IHf1.
rewrite IHf2.
destruct pol.
- +
- apply abs_and_pol; auto.
- +
- apply abs_or_pol; auto.
- - simpl.
+ + apply abs_and_pol; auto.
+ + apply abs_or_pol.
+ - simpl. unfold mk_or.
specialize (IHf1 pol).
specialize (IHf2 pol).
rewrite IHf1.
rewrite IHf2.
destruct pol.
- +
- apply abs_or_pol; auto.
- +
- apply abs_and_pol; auto.
+ + apply abs_or_pol; auto.
+ + apply abs_and_pol; auto.
- simpl.
+ unfold abs_not.
specialize (IHf (negb pol)).
destruct (is_X (abst_form (negb pol) f)) eqn:EQ1.
+ apply is_X_inv in EQ1.
@@ -699,381 +1111,438 @@ Section S.
simpl in *.
destruct pol ; auto.
+ simpl. congruence.
- - simpl.
+ - simpl. unfold mk_impl.
specialize (IHf1 (negb pol)).
specialize (IHf2 pol).
destruct pol.
- +
- simpl in *.
- unfold abs_or.
- destruct (is_X (abst_form false f1)) eqn:EQ1;
- destruct (is_X (abst_form true f2)) eqn:EQ2 ; simpl.
- * apply is_X_inv in EQ1.
- apply is_X_inv in EQ2.
- rewrite EQ1 in *.
- rewrite EQ2 in *.
- rewrite IHf1. rewrite IHf2.
- simpl. reflexivity.
- * apply is_X_inv in EQ1.
- rewrite EQ1 in *.
- rewrite IHf1.
- simpl.
- rewrite xcnf_true_mk_arrow_l.
- rewrite or_cnf_opt_cnf_ff.
- congruence.
- * apply is_X_inv in EQ2.
- rewrite EQ2 in *.
- rewrite IHf2.
- simpl.
- rewrite xcnf_true_mk_arrow_r.
- rewrite or_cnf_opt_cnf_ff_r.
- congruence.
- * destruct o ; simpl ; try congruence.
- rewrite EQ1.
- simpl. congruence.
- + simpl in *.
- unfold abs_and.
- destruct (is_X (abst_form true f1)) eqn:EQ1;
- destruct (is_X (abst_form false f2)) eqn:EQ2 ; simpl.
- * apply is_X_inv in EQ1.
+ +
+ simpl in *.
+ unfold abs_or.
+ destruct (is_X (abst_form false f1)) eqn:EQ1;
+ destruct (is_X (abst_form true f2)) eqn:EQ2 ; simpl.
+ * apply is_X_inv in EQ1.
+ apply is_X_inv in EQ2.
+ rewrite EQ1 in *.
+ rewrite EQ2 in *.
+ rewrite IHf1. rewrite IHf2.
+ simpl. reflexivity.
+ * apply is_X_inv in EQ1.
+ rewrite EQ1 in *.
+ rewrite IHf1.
+ simpl.
+ rewrite xcnf_true_mk_arrow_l.
+ rewrite or_cnf_opt_cnf_ff.
+ congruence.
+ * apply is_X_inv in EQ2.
+ rewrite EQ2 in *.
+ rewrite IHf2.
+ simpl.
+ rewrite xcnf_true_mk_arrow_r.
+ rewrite or_cnf_opt_cnf_ff_r.
+ congruence.
+ * destruct o ; simpl ; try congruence.
+ rewrite EQ1.
+ simpl. congruence.
+ + simpl in *.
+ unfold abs_and.
+ destruct (is_X (abst_form true f1)) eqn:EQ1;
+ destruct (is_X (abst_form false f2)) eqn:EQ2 ; simpl.
+ * apply is_X_inv in EQ1.
apply is_X_inv in EQ2.
rewrite EQ1 in *.
rewrite EQ2 in *.
rewrite IHf1. rewrite IHf2.
simpl. reflexivity.
- * apply is_X_inv in EQ1.
+ * apply is_X_inv in EQ1.
rewrite EQ1 in *.
rewrite IHf1.
simpl. reflexivity.
- * apply is_X_inv in EQ2.
+ * apply is_X_inv in EQ2.
rewrite EQ2 in *.
rewrite IHf2.
simpl. unfold and_cnf_opt.
rewrite orb_comm. reflexivity.
- * destruct o; simpl.
- rewrite EQ1. simpl.
- congruence.
- congruence.
- Qed.
-
- End Abstraction.
-
-
- End CNFAnnot.
-
-
- Lemma radd_term_term : forall a' a cl, radd_term a a' = inl cl -> add_term a a' = Some cl.
- Proof.
- induction a' ; simpl.
- - intros.
- destruct (deduce (fst a) (fst a)).
- destruct (unsat t). congruence.
- inversion H. reflexivity.
- inversion H ;reflexivity.
- - intros.
- destruct (deduce (fst a0) (fst a)).
- destruct (unsat t). congruence.
- destruct (radd_term a0 a') eqn:RADD; try congruence.
- inversion H. subst.
- apply IHa' in RADD.
- rewrite RADD.
- reflexivity.
- destruct (radd_term a0 a') eqn:RADD; try congruence.
- inversion H. subst.
- apply IHa' in RADD.
- rewrite RADD.
- reflexivity.
- Qed.
-
- Lemma radd_term_term' : forall a' a cl, add_term a a' = Some cl -> radd_term a a' = inl cl.
- Proof.
- induction a' ; simpl.
- - intros.
- destruct (deduce (fst a) (fst a)).
- destruct (unsat t). congruence.
- inversion H. reflexivity.
- inversion H ;reflexivity.
- - intros.
- destruct (deduce (fst a0) (fst a)).
- destruct (unsat t). congruence.
- destruct (add_term a0 a') eqn:RADD; try congruence.
- inversion H. subst.
- apply IHa' in RADD.
- rewrite RADD.
- reflexivity.
- destruct (add_term a0 a') eqn:RADD; try congruence.
- inversion H. subst.
- apply IHa' in RADD.
- rewrite RADD.
- reflexivity.
+ * destruct o; simpl.
+ rewrite EQ1. simpl.
+ congruence.
+ congruence.
+ - apply abst_iff_correct; auto.
+ - apply abst_eq_correct; auto.
Qed.
- Lemma xror_clause_clause : forall a f,
- fst (xror_clause_cnf a f) = xor_clause_cnf a f.
- Proof.
- unfold xror_clause_cnf.
- unfold xor_clause_cnf.
- assert (ACC: fst (@nil clause,@nil Annot) = nil).
- reflexivity.
- intros.
- set (F1:= (fun '(acc, tg) (e : clause) =>
- match ror_clause a e with
- | inl cl => (cl :: acc, tg)
- | inr l => (acc, tg +++ l)
- end)).
- set (F2:= (fun (acc : list clause) (e : clause) =>
- match or_clause a e with
- | Some cl => cl :: acc
- | None => acc
- end)).
- revert ACC.
- generalize (@nil clause,@nil Annot).
- generalize (@nil clause).
- induction f ; simpl ; auto.
- intros.
- apply IHf.
- unfold F1 , F2.
- destruct p ; simpl in * ; subst.
- clear.
- revert a0.
- induction a; simpl; auto.
- intros.
- destruct (radd_term a a1) eqn:RADD.
- apply radd_term_term in RADD.
- rewrite RADD.
- auto.
- destruct (add_term a a1) eqn:RADD'.
- apply radd_term_term' in RADD'.
- congruence.
- reflexivity.
- Qed.
+ End Abstraction.
- Lemma ror_clause_clause : forall a f,
- fst (ror_clause_cnf a f) = or_clause_cnf a f.
- Proof.
- unfold ror_clause_cnf,or_clause_cnf.
- destruct a ; auto.
- apply xror_clause_clause.
- Qed.
- Lemma ror_cnf_cnf : forall f1 f2, fst (ror_cnf f1 f2) = or_cnf f1 f2.
- Proof.
- induction f1 ; simpl ; auto.
- intros.
- specialize (IHf1 f2).
- destruct(ror_cnf f1 f2).
- rewrite <- ror_clause_clause.
- destruct(ror_clause_cnf a f2).
- simpl.
- rewrite <- IHf1.
- reflexivity.
- Qed.
+ End CNFAnnot.
- Lemma ror_opt_cnf_cnf : forall f1 f2, fst (ror_cnf_opt f1 f2) = or_cnf_opt f1 f2.
- Proof.
- unfold ror_cnf_opt, or_cnf_opt.
- intros.
- destruct (is_cnf_tt f1).
- - simpl ; auto.
- - simpl. destruct (is_cnf_tt f2) ; simpl ; auto.
- destruct (is_cnf_ff f2) eqn:EQ.
- reflexivity.
- apply ror_cnf_cnf.
- Qed.
- Lemma ratom_cnf : forall f a,
- fst (ratom f a) = f.
- Proof.
- unfold ratom.
- intros.
- destruct (is_cnf_ff f || is_cnf_tt f); auto.
- Qed.
-
-
-
- Lemma rxcnf_xcnf : forall {TX AF:Type} (f:TFormula TX AF) b,
- fst (rxcnf b f) = xcnf b f.
- Proof.
- induction f ; simpl ; auto.
- - destruct b; simpl ; auto.
- - destruct b; simpl ; auto.
- - destruct b ; simpl ; auto.
- - intros. rewrite ratom_cnf. reflexivity.
- - intros.
- specialize (IHf1 b).
- specialize (IHf2 b).
- destruct (rxcnf b f1).
- destruct (rxcnf b f2).
- simpl in *.
- subst. destruct b ; auto.
- rewrite <- ror_opt_cnf_cnf.
- destruct (ror_cnf_opt (xcnf false f1) (xcnf false f2)).
- reflexivity.
- - intros.
- specialize (IHf1 b).
- specialize (IHf2 b).
- rewrite <- IHf1.
- rewrite <- IHf2.
- destruct (rxcnf b f1).
- destruct (rxcnf b f2).
- simpl in *.
- subst. destruct b ; auto.
- rewrite <- ror_opt_cnf_cnf.
- destruct (ror_cnf_opt (xcnf true f1) (xcnf true f2)).
- reflexivity.
- - intros.
- specialize (IHf1 (negb b)).
- specialize (IHf2 b).
- rewrite <- IHf1.
- rewrite <- IHf2.
- destruct (rxcnf (negb b) f1).
- destruct (rxcnf b f2).
- simpl in *.
- subst.
- destruct b;auto.
- generalize (is_cnf_ff_inv (xcnf (negb true) f1)).
- destruct (is_cnf_ff (xcnf (negb true) f1)).
- + intros.
- rewrite H by auto.
- unfold or_cnf_opt.
- simpl.
- destruct (is_cnf_tt (xcnf true f2)) eqn:EQ;auto.
- apply is_cnf_tt_inv in EQ; auto.
- destruct (is_cnf_ff (xcnf true f2)) eqn:EQ1.
- apply is_cnf_ff_inv in EQ1. congruence.
- reflexivity.
- +
- rewrite <- ror_opt_cnf_cnf.
- destruct (ror_cnf_opt (xcnf (negb true) f1) (xcnf true f2)).
- intros.
- reflexivity.
- Qed.
+ Lemma radd_term_term : forall a' a cl, radd_term a a' = inl cl -> add_term a a' = Some cl.
+ Proof.
+ induction a' ; simpl.
+ - intros.
+ destruct (deduce (fst a) (fst a)).
+ destruct (unsat t). congruence.
+ inversion H. reflexivity.
+ inversion H ;reflexivity.
+ - intros.
+ destruct (deduce (fst a0) (fst a)).
+ destruct (unsat t). congruence.
+ destruct (radd_term a0 a') eqn:RADD; try congruence.
+ inversion H. subst.
+ apply IHa' in RADD.
+ rewrite RADD.
+ reflexivity.
+ destruct (radd_term a0 a') eqn:RADD; try congruence.
+ inversion H. subst.
+ apply IHa' in RADD.
+ rewrite RADD.
+ reflexivity.
+ Qed.
+ Lemma radd_term_term' : forall a' a cl, add_term a a' = Some cl -> radd_term a a' = inl cl.
+ Proof.
+ induction a' ; simpl.
+ - intros.
+ destruct (deduce (fst a) (fst a)).
+ destruct (unsat t). congruence.
+ inversion H. reflexivity.
+ inversion H ;reflexivity.
+ - intros.
+ destruct (deduce (fst a0) (fst a)).
+ destruct (unsat t). congruence.
+ destruct (add_term a0 a') eqn:RADD; try congruence.
+ inversion H. subst.
+ apply IHa' in RADD.
+ rewrite RADD.
+ reflexivity.
+ destruct (add_term a0 a') eqn:RADD; try congruence.
+ inversion H. subst.
+ apply IHa' in RADD.
+ rewrite RADD.
+ reflexivity.
+ Qed.
- Variable eval' : Env -> Term' -> Prop.
+ Lemma xror_clause_clause : forall a f,
+ fst (xror_clause_cnf a f) = xor_clause_cnf a f.
+ Proof.
+ unfold xror_clause_cnf.
+ unfold xor_clause_cnf.
+ assert (ACC: fst (@nil clause,@nil Annot) = nil).
+ reflexivity.
+ intros.
+ set (F1:= (fun '(acc, tg) (e : clause) =>
+ match ror_clause a e with
+ | inl cl => (cl :: acc, tg)
+ | inr l => (acc, tg +++ l)
+ end)).
+ set (F2:= (fun (acc : list clause) (e : clause) =>
+ match or_clause a e with
+ | Some cl => cl :: acc
+ | None => acc
+ end)).
+ revert ACC.
+ generalize (@nil clause,@nil Annot).
+ generalize (@nil clause).
+ induction f ; simpl ; auto.
+ intros.
+ apply IHf.
+ unfold F1 , F2.
+ destruct p ; simpl in * ; subst.
+ clear.
+ revert a0.
+ induction a; simpl; auto.
+ intros.
+ destruct (radd_term a a1) eqn:RADD.
+ apply radd_term_term in RADD.
+ rewrite RADD.
+ auto.
+ destruct (add_term a a1) eqn:RADD'.
+ apply radd_term_term' in RADD'.
+ congruence.
+ reflexivity.
+ Qed.
- Variable no_middle_eval' : forall env d, (eval' env d) \/ ~ (eval' env d).
+ Lemma ror_clause_clause : forall a f,
+ fst (ror_clause_cnf a f) = or_clause_cnf a f.
+ Proof.
+ unfold ror_clause_cnf,or_clause_cnf.
+ destruct a ; auto.
+ apply xror_clause_clause.
+ Qed.
+ Lemma ror_cnf_cnf : forall f1 f2, fst (ror_cnf f1 f2) = or_cnf f1 f2.
+ Proof.
+ induction f1 ; simpl ; auto.
+ intros.
+ specialize (IHf1 f2).
+ destruct(ror_cnf f1 f2).
+ rewrite <- ror_clause_clause.
+ destruct(ror_clause_cnf a f2).
+ simpl.
+ rewrite <- IHf1.
+ reflexivity.
+ Qed.
- Variable unsat_prop : forall t, unsat t = true ->
- forall env, eval' env t -> False.
+ Lemma ror_opt_cnf_cnf : forall f1 f2, fst (ror_cnf_opt f1 f2) = or_cnf_opt f1 f2.
+ Proof.
+ unfold ror_cnf_opt, or_cnf_opt.
+ intros.
+ destruct (is_cnf_tt f1).
+ - simpl ; auto.
+ - simpl. destruct (is_cnf_tt f2) ; simpl ; auto.
+ destruct (is_cnf_ff f2) eqn:EQ.
+ reflexivity.
+ apply ror_cnf_cnf.
+ Qed.
+ Lemma ratom_cnf : forall f a,
+ fst (ratom f a) = f.
+ Proof.
+ unfold ratom.
+ intros.
+ destruct (is_cnf_ff f || is_cnf_tt f); auto.
+ Qed.
+ Lemma rxcnf_and_xcnf : forall {TX : kind -> Type} {AF:Type} (k: kind) (f1 f2:TFormula TX AF k)
+ (IHf1 : forall pol : bool, fst (rxcnf pol f1) = xcnf pol f1)
+ (IHf2 : forall pol : bool, fst (rxcnf pol f2) = xcnf pol f2),
+ forall pol : bool, fst (rxcnf_and rxcnf pol f1 f2) = mk_and xcnf pol f1 f2.
+ Proof.
+ intros.
+ unfold mk_and, rxcnf_and.
+ specialize (IHf1 pol).
+ specialize (IHf2 pol).
+ destruct (rxcnf pol f1).
+ destruct (rxcnf pol f2).
+ simpl in *.
+ subst. destruct pol ; auto.
+ rewrite <- ror_opt_cnf_cnf.
+ destruct (ror_cnf_opt (xcnf false f1) (xcnf false f2)).
+ reflexivity.
+ Qed.
- Variable deduce_prop : forall t t' u,
- deduce t t' = Some u -> forall env,
- eval' env t -> eval' env t' -> eval' env u.
+ Lemma rxcnf_or_xcnf :
+ forall {TX : kind -> Type} {AF:Type} (k: kind) (f1 f2:TFormula TX AF k)
+ (IHf1 : forall pol : bool, fst (rxcnf pol f1) = xcnf pol f1)
+ (IHf2 : forall pol : bool, fst (rxcnf pol f2) = xcnf pol f2),
+ forall pol : bool, fst (rxcnf_or rxcnf pol f1 f2) = mk_or xcnf pol f1 f2.
+ Proof.
+ intros.
+ unfold rxcnf_or, mk_or.
+ specialize (IHf1 pol).
+ specialize (IHf2 pol).
+ destruct (rxcnf pol f1).
+ destruct (rxcnf pol f2).
+ simpl in *.
+ subst. destruct pol ; auto.
+ rewrite <- ror_opt_cnf_cnf.
+ destruct (ror_cnf_opt (xcnf true f1) (xcnf true f2)).
+ reflexivity.
+ Qed.
+ Lemma rxcnf_impl_xcnf :
+ forall {TX : kind -> Type} {AF:Type} (k: kind) (f1 f2:TFormula TX AF k)
+ (IHf1 : forall pol : bool, fst (rxcnf pol f1) = xcnf pol f1)
+ (IHf2 : forall pol : bool, fst (rxcnf pol f2) = xcnf pol f2),
+ forall pol : bool, fst (rxcnf_impl rxcnf pol f1 f2) = mk_impl xcnf pol f1 f2.
+ Proof.
+ intros.
+ unfold rxcnf_impl, mk_impl, mk_or.
+ specialize (IHf1 (negb pol)).
+ specialize (IHf2 pol).
+ rewrite <- IHf1.
+ rewrite <- IHf2.
+ destruct (rxcnf (negb pol) f1).
+ destruct (rxcnf pol f2).
+ simpl in *.
+ subst.
+ destruct pol;auto.
+ generalize (is_cnf_ff_inv (xcnf (negb true) f1)).
+ destruct (is_cnf_ff (xcnf (negb true) f1)).
+ + intros.
+ rewrite H by auto.
+ unfold or_cnf_opt.
+ simpl.
+ destruct (is_cnf_tt (xcnf true f2)) eqn:EQ;auto.
+ apply is_cnf_tt_inv in EQ; auto.
+ destruct (is_cnf_ff (xcnf true f2)) eqn:EQ1.
+ apply is_cnf_ff_inv in EQ1. congruence.
+ reflexivity.
+ +
+ rewrite <- ror_opt_cnf_cnf.
+ destruct (ror_cnf_opt (xcnf (negb true) f1) (xcnf true f2)).
+ intros.
+ reflexivity.
+ Qed.
- Definition eval_tt (env : Env) (tt : Term' * Annot) := eval' env (fst tt).
- Definition eval_clause (env : Env) (cl : clause) := ~ make_conj (eval_tt env) cl.
+ Lemma rxcnf_iff_xcnf :
+ forall {TX : kind -> Type} {AF:Type} (k: kind) (f1 f2:TFormula TX AF k)
+ (IHf1 : forall pol : bool, fst (rxcnf pol f1) = xcnf pol f1)
+ (IHf2 : forall pol : bool, fst (rxcnf pol f2) = xcnf pol f2),
+ forall pol : bool, fst (rxcnf_iff rxcnf pol f1 f2) = mk_iff xcnf pol f1 f2.
+ Proof.
+ intros.
+ unfold rxcnf_iff.
+ unfold mk_iff.
+ rewrite <- (IHf1 (negb pol)).
+ rewrite <- (IHf1 pol).
+ rewrite <- (IHf2 false).
+ rewrite <- (IHf2 true).
+ destruct (rxcnf (negb pol) f1).
+ destruct (rxcnf false f2).
+ destruct (rxcnf pol f1).
+ destruct (rxcnf true f2).
+ destruct (ror_cnf_opt (and_cnf_opt c c0) (and_cnf_opt c1 c2)) eqn:EQ.
+ simpl.
+ change c3 with (fst (c3,l3)).
+ rewrite <- EQ. rewrite ror_opt_cnf_cnf.
+ reflexivity.
+ Qed.
- Definition eval_cnf (env : Env) (f:cnf) := make_conj (eval_clause env) f.
+ Lemma rxcnf_xcnf : forall {TX : kind -> Type} {AF:Type} (k: kind) (f:TFormula TX AF k) pol,
+ fst (rxcnf pol f) = xcnf pol f.
+ Proof.
+ induction f ; simpl ; auto.
+ - destruct pol; simpl ; auto.
+ - destruct pol; simpl ; auto.
+ - destruct pol ; simpl ; auto.
+ - intros. rewrite ratom_cnf. reflexivity.
+ - apply rxcnf_and_xcnf; auto.
+ - apply rxcnf_or_xcnf; auto.
+ - apply rxcnf_impl_xcnf; auto.
+ - intros.
+ rewrite mk_iff_is_bool.
+ apply rxcnf_iff_xcnf; auto.
+ - intros.
+ rewrite mk_iff_is_bool.
+ apply rxcnf_iff_xcnf; auto.
+ Qed.
- Lemma eval_cnf_app : forall env x y, eval_cnf env (x+++y) <-> eval_cnf env x /\ eval_cnf env y.
- Proof.
- unfold eval_cnf.
- intros.
- rewrite make_conj_rapp.
- rewrite make_conj_app ; auto.
- tauto.
- Qed.
+ Variable eval' : Env -> Term' -> Prop.
+ Variable no_middle_eval' : forall env d, (eval' env d) \/ ~ (eval' env d).
- Lemma eval_cnf_ff : forall env, eval_cnf env cnf_ff <-> False.
- Proof.
- unfold cnf_ff, eval_cnf,eval_clause.
- simpl. tauto.
- Qed.
+ Variable unsat_prop : forall t, unsat t = true ->
+ forall env, eval' env t -> False.
- Lemma eval_cnf_tt : forall env, eval_cnf env cnf_tt <-> True.
- Proof.
- unfold cnf_tt, eval_cnf,eval_clause.
- simpl. tauto.
- Qed.
+ Variable deduce_prop : forall t t' u,
+ deduce t t' = Some u -> forall env,
+ eval' env t -> eval' env t' -> eval' env u.
+ Definition eval_tt (env : Env) (tt : Term' * Annot) := eval' env (fst tt).
- Lemma eval_cnf_and_opt : forall env x y, eval_cnf env (and_cnf_opt x y) <-> eval_cnf env (and_cnf x y).
- Proof.
- unfold and_cnf_opt.
- intros.
- destruct (is_cnf_ff x) eqn:F1.
- { apply is_cnf_ff_inv in F1.
- simpl. subst.
- unfold and_cnf.
- rewrite eval_cnf_app.
- rewrite eval_cnf_ff.
- tauto.
- }
- simpl.
- destruct (is_cnf_ff y) eqn:F2.
- { apply is_cnf_ff_inv in F2.
- simpl. subst.
- unfold and_cnf.
- rewrite eval_cnf_app.
- rewrite eval_cnf_ff.
- tauto.
- }
- tauto.
- Qed.
+ Definition eval_clause (env : Env) (cl : clause) := ~ make_conj (eval_tt env) cl.
+ Definition eval_cnf (env : Env) (f:cnf) := make_conj (eval_clause env) f.
+ Lemma eval_cnf_app : forall env x y, eval_cnf env (x+++y) <-> eval_cnf env x /\ eval_cnf env y.
+ Proof.
+ unfold eval_cnf.
+ intros.
+ rewrite make_conj_rapp.
+ rewrite make_conj_app ; auto.
+ tauto.
+ Qed.
- Definition eval_opt_clause (env : Env) (cl: option clause) :=
- match cl with
- | None => True
- | Some cl => eval_clause env cl
- end.
+ Lemma eval_cnf_ff : forall env, eval_cnf env cnf_ff <-> False.
+ Proof.
+ unfold cnf_ff, eval_cnf,eval_clause.
+ simpl. tauto.
+ Qed.
+ Lemma eval_cnf_tt : forall env, eval_cnf env cnf_tt <-> True.
+ Proof.
+ unfold cnf_tt, eval_cnf,eval_clause.
+ simpl. tauto.
+ Qed.
- Lemma add_term_correct : forall env t cl , eval_opt_clause env (add_term t cl) <-> eval_clause env (t::cl).
+ Lemma eval_cnf_and_opt : forall env x y, eval_cnf env (and_cnf_opt x y) <-> eval_cnf env (and_cnf x y).
Proof.
- induction cl.
- - (* BC *)
- simpl.
- case_eq (deduce (fst t) (fst t)) ; try tauto.
+ unfold and_cnf_opt.
intros.
- generalize (@deduce_prop _ _ _ H env).
- case_eq (unsat t0) ; try tauto.
- { intros.
- generalize (@unsat_prop _ H0 env).
- unfold eval_clause.
- rewrite make_conj_cons.
- simpl; intros.
+ destruct (is_cnf_ff x) eqn:F1.
+ { apply is_cnf_ff_inv in F1.
+ simpl. subst.
+ unfold and_cnf.
+ rewrite eval_cnf_app.
+ rewrite eval_cnf_ff.
tauto.
}
- - (* IC *)
simpl.
- case_eq (deduce (fst t) (fst a));
- intros.
- generalize (@deduce_prop _ _ _ H env).
- case_eq (unsat t0); intros.
- {
- generalize (@unsat_prop _ H0 env).
- simpl.
- unfold eval_clause.
- repeat rewrite make_conj_cons.
- tauto.
- }
- destruct (add_term t cl) ; simpl in * ; try tauto.
- {
- intros.
- unfold eval_clause in *.
- repeat rewrite make_conj_cons in *.
+ destruct (is_cnf_ff y) eqn:F2.
+ { apply is_cnf_ff_inv in F2.
+ simpl. subst.
+ unfold and_cnf.
+ rewrite eval_cnf_app.
+ rewrite eval_cnf_ff.
tauto.
}
+ destruct (is_cnf_tt y) eqn:F3.
{
- unfold eval_clause in *.
- repeat rewrite make_conj_cons in *.
+ apply is_cnf_tt_inv in F3.
+ subst.
+ unfold and_cnf.
+ rewrite eval_cnf_app.
+ rewrite eval_cnf_tt.
tauto.
}
- destruct (add_term t cl) ; simpl in *;
- unfold eval_clause in * ;
- repeat rewrite make_conj_cons in *; tauto.
+ tauto.
+ Qed.
+
+ Definition eval_opt_clause (env : Env) (cl: option clause) :=
+ match cl with
+ | None => True
+ | Some cl => eval_clause env cl
+ end.
+
+ Lemma add_term_correct : forall env t cl , eval_opt_clause env (add_term t cl) <-> eval_clause env (t::cl).
+ Proof.
+ induction cl.
+ - (* BC *)
+ simpl.
+ case_eq (deduce (fst t) (fst t)) ; try tauto.
+ intros.
+ generalize (@deduce_prop _ _ _ H env).
+ case_eq (unsat t0) ; try tauto.
+ { intros.
+ generalize (@unsat_prop _ H0 env).
+ unfold eval_clause.
+ rewrite make_conj_cons.
+ simpl; intros.
+ tauto.
+ }
+ - (* IC *)
+ simpl.
+ case_eq (deduce (fst t) (fst a));
+ intros.
+ generalize (@deduce_prop _ _ _ H env).
+ case_eq (unsat t0); intros.
+ {
+ generalize (@unsat_prop _ H0 env).
+ simpl.
+ unfold eval_clause.
+ repeat rewrite make_conj_cons.
+ tauto.
+ }
+ destruct (add_term t cl) ; simpl in * ; try tauto.
+ {
+ intros.
+ unfold eval_clause in *.
+ repeat rewrite make_conj_cons in *.
+ tauto.
+ }
+ {
+ unfold eval_clause in *.
+ repeat rewrite make_conj_cons in *.
+ tauto.
+ }
+ destruct (add_term t cl) ; simpl in *;
+ unfold eval_clause in * ;
+ repeat rewrite make_conj_cons in *; tauto.
Qed.
@@ -1096,10 +1565,10 @@ Section S.
assert (eval_tt env a \/ ~ eval_tt env a) by (apply no_middle_eval').
destruct (add_term a cl'); simpl in *.
+
- rewrite IHcl.
- unfold eval_clause in *.
- rewrite !make_conj_cons in *.
- tauto.
+ rewrite IHcl.
+ unfold eval_clause in *.
+ rewrite !make_conj_cons in *.
+ tauto.
+ unfold eval_clause in *.
repeat rewrite make_conj_cons in *.
tauto.
@@ -1131,8 +1600,8 @@ Section S.
generalize (or_clause_correct t a env).
destruct (or_clause t a).
+
- rewrite make_conj_cons.
- simpl. tauto.
+ rewrite make_conj_cons.
+ simpl. tauto.
+ simpl. tauto.
}
destruct t ; auto.
@@ -1211,113 +1680,108 @@ Section S.
}
Qed.
+ Variable eval : Env -> forall (k: kind), Term -> rtyp k.
- Variable eval : Env -> Term -> Prop.
+ Variable normalise_correct : forall env b t tg, eval_cnf env (normalise t tg) -> hold b (eval env b t).
- Variable normalise_correct : forall env t tg, eval_cnf env (normalise t tg) -> eval env t.
+ Variable negate_correct : forall env b t tg, eval_cnf env (negate t tg) -> hold b (eNOT b (eval env b t)).
- Variable negate_correct : forall env t tg, eval_cnf env (negate t tg) -> ~ eval env t.
+ Definition e_rtyp (k: kind) (x : rtyp k) : rtyp k := x.
- Lemma xcnf_correct : forall (f : @GFormula Term Prop Annot unit) pol env, eval_cnf env (xcnf pol f) -> eval_f (fun x => x) (eval env) (if pol then f else N f).
+ Lemma hold_eTT : forall k, hold k (eTT k).
Proof.
- induction f.
- - (* TT *)
- unfold eval_cnf.
- simpl.
- destruct pol ; simpl ; auto.
- - (* FF *)
- unfold eval_cnf.
- destruct pol; simpl ; auto.
- unfold eval_clause ; simpl.
- tauto.
- - (* P *)
- simpl.
- destruct pol ; intros ;simpl.
- unfold eval_cnf in H.
- (* Here I have to drop the proposition *)
- simpl in H.
- unfold eval_clause in H ; simpl in H.
- tauto.
- (* Here, I could store P in the clause *)
- unfold eval_cnf in H;simpl in H.
- unfold eval_clause in H ; simpl in H.
- tauto.
- - (* A *)
- simpl.
- destruct pol ; simpl.
- intros.
- eapply normalise_correct ; eauto.
- (* A 2 *)
- intros.
- eapply negate_correct ; eauto.
- - (* Cj *)
- destruct pol ; simpl.
- + (* pol = true *)
- intros.
- rewrite eval_cnf_and_opt in H.
- unfold and_cnf in H.
- rewrite eval_cnf_app in H.
- destruct H.
- split.
- apply (IHf1 _ _ H).
- apply (IHf2 _ _ H0).
- + (* pol = false *)
- intros.
- rewrite or_cnf_opt_correct in H.
- rewrite or_cnf_correct in H.
- destruct H as [H | H].
- generalize (IHf1 false env H).
- simpl.
- tauto.
- generalize (IHf2 false env H).
- simpl.
- tauto.
- - (* D *)
- simpl.
- destruct pol.
- + (* pol = true *)
- intros.
- rewrite or_cnf_opt_correct in H.
- rewrite or_cnf_correct in H.
- destruct H as [H | H].
- generalize (IHf1 _ env H).
- simpl.
- tauto.
- generalize (IHf2 _ env H).
- simpl.
- tauto.
- + (* pol = true *)
- intros.
- rewrite eval_cnf_and_opt in H.
- unfold and_cnf.
- rewrite eval_cnf_app in H.
- destruct H as [H0 H1].
- simpl.
- generalize (IHf1 _ _ H0).
- generalize (IHf2 _ _ H1).
- simpl.
- tauto.
- - (**)
- simpl.
- destruct pol ; simpl.
- intros.
- apply (IHf false) ; auto.
- intros.
- generalize (IHf _ _ H).
- tauto.
- - (* I *)
- simpl; intros.
+ destruct k ; simpl; auto.
+ Qed.
+
+ Hint Resolve hold_eTT : tauto.
+
+ Lemma hold_eFF : forall k,
+ hold k (eNOT k (eFF k)).
+ Proof.
+ destruct k ; simpl;auto.
+ Qed.
+
+ Hint Resolve hold_eFF : tauto.
+
+ Lemma hold_eAND : forall k r1 r2,
+ hold k (eAND k r1 r2) <-> (hold k r1 /\ hold k r2).
+ Proof.
+ destruct k ; simpl.
+ - intros. apply iff_refl.
+ - apply andb_true_iff.
+ Qed.
+
+ Lemma hold_eOR : forall k r1 r2,
+ hold k (eOR k r1 r2) <-> (hold k r1 \/ hold k r2).
+ Proof.
+ destruct k ; simpl.
+ - intros. apply iff_refl.
+ - apply orb_true_iff.
+ Qed.
+
+ Lemma hold_eNOT : forall k e,
+ hold k (eNOT k e) <-> not (hold k e).
+ Proof.
+ destruct k ; simpl.
+ - intros. apply iff_refl.
+ - intros. unfold is_true.
+ rewrite negb_true_iff.
+ destruct e ; intuition congruence.
+ Qed.
+
+ Lemma hold_eIMPL : forall k e1 e2,
+ hold k (eIMPL k e1 e2) <-> (hold k e1 -> hold k e2).
+ Proof.
+ destruct k ; simpl.
+ - intros. apply iff_refl.
+ - intros.
+ unfold is_true.
+ destruct e1,e2 ; simpl ; intuition congruence.
+ Qed.
+
+ Lemma hold_eIFF : forall k e1 e2,
+ hold k (eIFF k e1 e2) <-> (hold k e1 <-> hold k e2).
+ Proof.
+ destruct k ; simpl.
+ - intros. apply iff_refl.
+ - intros.
+ unfold is_true.
+ rewrite eqb_true_iff.
+ destruct e1,e2 ; simpl ; intuition congruence.
+ Qed.
+
+
+
+ Lemma xcnf_impl :
+ forall
+ (k: kind)
+ (f1 : GFormula k)
+ (o : option unit)
+ (f2 : GFormula k)
+ (IHf1 : forall (pol : bool) (env : Env),
+ eval_cnf env (xcnf pol f1) ->
+ hold k (eval_f e_rtyp (eval env) (if pol then f1 else NOT f1)))
+ (IHf2 : forall (pol : bool) (env : Env),
+ eval_cnf env (xcnf pol f2) ->
+ hold k (eval_f e_rtyp (eval env) (if pol then f2 else NOT f2))),
+ forall (pol : bool) (env : Env),
+ eval_cnf env (xcnf pol (IMPL f1 o f2)) ->
+ hold k (eval_f e_rtyp (eval env) (if pol then IMPL f1 o f2 else NOT (IMPL f1 o f2))).
+ Proof.
+ simpl; intros. unfold mk_impl in H.
destruct pol.
+ simpl.
- intro.
- rewrite or_cnf_opt_correct in H.
- rewrite or_cnf_correct in H.
- destruct H as [H | H].
- generalize (IHf1 _ _ H).
- simpl in *.
- tauto.
- generalize (IHf2 _ _ H).
- auto.
+ rewrite hold_eIMPL.
+ intro.
+ rewrite or_cnf_opt_correct in H.
+ rewrite or_cnf_correct in H.
+ destruct H as [H | H].
+ generalize (IHf1 _ _ H).
+ simpl in *.
+ rewrite hold_eNOT.
+ tauto.
+ generalize (IHf2 _ _ H).
+ auto.
+ (* pol = false *)
rewrite eval_cnf_and_opt in H.
unfold and_cnf in H.
@@ -1327,9 +1791,190 @@ Section S.
generalize (IHf1 _ _ H0).
generalize (IHf2 _ _ H1).
simpl.
+ rewrite ! hold_eNOT.
+ rewrite ! hold_eIMPL.
tauto.
Qed.
+ Lemma hold_eIFF_IMPL : forall k e1 e2,
+ hold k (eIFF k e1 e2) <-> (hold k (eAND k (eIMPL k e1 e2) (eIMPL k e2 e1))).
+ Proof.
+ intros.
+ rewrite hold_eIFF.
+ rewrite hold_eAND.
+ rewrite! hold_eIMPL.
+ tauto.
+ Qed.
+
+ Lemma hold_eEQ : forall e1 e2,
+ hold isBool (eIFF isBool e1 e2) <-> e1 = e2.
+ Proof.
+ simpl.
+ destruct e1,e2 ; simpl ; intuition congruence.
+ Qed.
+
+
+ Lemma xcnf_iff : forall
+ (k : kind)
+ (f1 f2 : @GFormula Term rtyp Annot unit k)
+ (IHf1 : forall (pol : bool) (env : Env),
+ eval_cnf env (xcnf pol f1) ->
+ hold k (eval_f e_rtyp (eval env) (if pol then f1 else NOT f1)))
+ (IHf2 : forall (pol : bool) (env : Env),
+ eval_cnf env (xcnf pol f2) ->
+ hold k (eval_f e_rtyp (eval env) (if pol then f2 else NOT f2))),
+ forall (pol : bool) (env : Env),
+ eval_cnf env (xcnf pol (IFF f1 f2)) ->
+ hold k (eval_f e_rtyp (eval env) (if pol then IFF f1 f2 else NOT (IFF f1 f2))).
+ Proof.
+ simpl.
+ intros.
+ rewrite mk_iff_is_bool in H.
+ unfold mk_iff in H.
+ destruct pol;
+ rewrite or_cnf_opt_correct in H;
+ rewrite or_cnf_correct in H;
+ rewrite! eval_cnf_and_opt in H;
+ unfold and_cnf in H;
+ rewrite! eval_cnf_app in H;
+ generalize (IHf1 false env);
+ generalize (IHf1 true env);
+ generalize (IHf2 false env);
+ generalize (IHf2 true env);
+ simpl.
+ -
+ rewrite hold_eIFF_IMPL.
+ rewrite hold_eAND.
+ rewrite! hold_eIMPL.
+ rewrite! hold_eNOT.
+ tauto.
+ - rewrite! hold_eNOT.
+ rewrite hold_eIFF_IMPL.
+ rewrite hold_eAND.
+ rewrite! hold_eIMPL.
+ tauto.
+ Qed.
+
+ Lemma xcnf_correct : forall (k: kind) (f : @GFormula Term rtyp Annot unit k) pol env,
+ eval_cnf env (xcnf pol f) -> hold k (eval_f e_rtyp (eval env) (if pol then f else NOT f)).
+ Proof.
+ induction f.
+ - (* TT *)
+ unfold eval_cnf.
+ simpl.
+ destruct pol ; intros; simpl; auto with tauto.
+ rewrite eval_cnf_ff in H. tauto.
+ - (* FF *)
+ destruct pol ; simpl in *; intros; auto with tauto.
+ + rewrite eval_cnf_ff in H. tauto.
+ - (* P *)
+ simpl.
+ destruct pol ; intros ;simpl.
+ + rewrite eval_cnf_ff in H. tauto.
+ + rewrite eval_cnf_ff in H. tauto.
+ - (* A *)
+ simpl.
+ destruct pol ; simpl.
+ intros.
+ eapply normalise_correct ; eauto.
+ (* A 2 *)
+ intros.
+ eapply negate_correct ; eauto.
+ - (* AND *)
+ destruct pol ; simpl.
+ + (* pol = true *)
+ intros.
+ rewrite eval_cnf_and_opt in H.
+ unfold and_cnf in H.
+ rewrite eval_cnf_app in H.
+ destruct H.
+ apply hold_eAND; split.
+ apply (IHf1 _ _ H).
+ apply (IHf2 _ _ H0).
+ + (* pol = false *)
+ intros.
+ apply hold_eNOT.
+ rewrite hold_eAND.
+ rewrite or_cnf_opt_correct in H.
+ rewrite or_cnf_correct in H.
+ destruct H as [H | H].
+ generalize (IHf1 false env H).
+ simpl.
+ rewrite hold_eNOT.
+ tauto.
+ generalize (IHf2 false env H).
+ simpl.
+ rewrite hold_eNOT.
+ tauto.
+ - (* OR *)
+ simpl.
+ destruct pol.
+ + (* pol = true *)
+ intros. unfold mk_or in H.
+ rewrite or_cnf_opt_correct in H.
+ rewrite or_cnf_correct in H.
+ destruct H as [H | H].
+ generalize (IHf1 _ env H).
+ simpl.
+ rewrite hold_eOR.
+ tauto.
+ generalize (IHf2 _ env H).
+ simpl.
+ rewrite hold_eOR.
+ tauto.
+ + (* pol = true *)
+ intros. unfold mk_or in H.
+ rewrite eval_cnf_and_opt in H.
+ unfold and_cnf.
+ rewrite eval_cnf_app in H.
+ destruct H as [H0 H1].
+ simpl.
+ generalize (IHf1 _ _ H0).
+ generalize (IHf2 _ _ H1).
+ simpl.
+ rewrite ! hold_eNOT.
+ rewrite ! hold_eOR.
+ tauto.
+ - (**)
+ simpl.
+ destruct pol ; simpl.
+ intros.
+ apply (IHf false) ; auto.
+ intros.
+ generalize (IHf _ _ H).
+ rewrite ! hold_eNOT.
+ tauto.
+ - (* IMPL *)
+ apply xcnf_impl; auto.
+ - apply xcnf_iff ; auto.
+ - simpl.
+ destruct (is_bool f2) eqn:EQ.
+ + apply is_bool_inv in EQ.
+ destruct b; subst; intros;
+ apply IHf1 in H;
+ destruct pol ; simpl in * ; auto.
+ * unfold is_true in H.
+ rewrite negb_true_iff in H.
+ congruence.
+ *
+ unfold is_true in H.
+ rewrite negb_true_iff in H.
+ congruence.
+ * unfold is_true in H.
+ congruence.
+ + intros.
+ rewrite <- mk_iff_is_bool in H.
+ apply xcnf_iff in H; auto.
+ simpl in H.
+ destruct pol ; simpl in *.
+ rewrite <- hold_eEQ.
+ simpl; auto.
+ rewrite <- hold_eEQ.
+ simpl; auto.
+ unfold is_true in *.
+ rewrite negb_true_iff in H.
+ congruence.
+ Qed.
Variable Witness : Type.
Variable checker : list (Term'*Annot) -> Witness -> bool.
@@ -1370,28 +2015,26 @@ Section S.
tauto.
Qed.
-
- Definition tauto_checker (f:@GFormula Term Prop Annot unit) (w:list Witness) : bool :=
+ Definition tauto_checker (f:@GFormula Term rtyp Annot unit isProp) (w:list Witness) : bool :=
cnf_checker (xcnf true f) w.
- Lemma tauto_checker_sound : forall t w, tauto_checker t w = true -> forall env, eval_f (fun x => x) (eval env) t.
+ Lemma tauto_checker_sound : forall t w, tauto_checker t w = true -> forall env, eval_f e_rtyp (eval env) t.
Proof.
unfold tauto_checker.
intros.
- change (eval_f (fun x => x) (eval env) t) with (eval_f (fun x => x) (eval env) (if true then t else TT)).
+ change (eval_f e_rtyp (eval env) t) with (eval_f e_rtyp (eval env) (if true then t else TT isProp)).
apply (xcnf_correct t true).
eapply cnf_checker_sound ; eauto.
Qed.
- Definition eval_bf {A : Type} (ea : A -> Prop) (f: BFormula A) := eval_f (fun x => x) ea f.
-
+ Definition eval_bf {A : Type} (ea : forall (k: kind), A -> rtyp k) (k: kind) (f: BFormula A k) := eval_f e_rtyp ea f.
- Lemma eval_bf_map : forall T U (fct: T-> U) env f ,
- eval_bf env (map_bformula fct f) = eval_bf (fun x => env (fct x)) f.
-Proof.
- induction f ; simpl ; try (rewrite IHf1 ; rewrite IHf2) ; auto.
- rewrite <- IHf. auto.
-Qed.
+ Lemma eval_bf_map : forall T U (fct: T-> U) env (k: kind) (f:BFormula T k) ,
+ eval_bf env (map_bformula fct f) = eval_bf (fun b x => env b (fct x)) f.
+ Proof.
+ induction f ; simpl ; try (rewrite IHf1 ; rewrite IHf2) ; auto.
+ rewrite <- IHf. auto.
+ Qed.
End S.
diff --git a/theories/micromega/ZMicromega.v b/theories/micromega/ZMicromega.v
index bff9671fee..935757f30a 100644
--- a/theories/micromega/ZMicromega.v
+++ b/theories/micromega/ZMicromega.v
@@ -176,7 +176,7 @@ Proof.
rewrite ZNpower. congruence.
Qed.
-Definition Zeval_op2 (o : Op2) : Z -> Z -> Prop :=
+Definition Zeval_pop2 (o : Op2) : Z -> Z -> Prop :=
match o with
| OpEq => @eq Z
| OpNEq => fun x y => ~ x = y
@@ -187,14 +187,62 @@ match o with
end.
-Definition Zeval_formula (env : PolEnv Z) (f : Formula Z):=
+Definition Zeval_bop2 (o : Op2) : Z -> Z -> bool :=
+match o with
+| OpEq => Z.eqb
+| OpNEq => fun x y => negb (Z.eqb x y)
+| OpLe => Z.leb
+| OpGe => Z.geb
+| OpLt => Z.ltb
+| OpGt => Z.gtb
+end.
+
+Lemma pop2_bop2 :
+ forall (op : Op2) (q1 q2 : Z), is_true (Zeval_bop2 op q1 q2) <-> Zeval_pop2 op q1 q2.
+Proof.
+ unfold is_true.
+ destruct op ; simpl; intros.
+ - apply Z.eqb_eq.
+ - rewrite <- Z.eqb_eq.
+ rewrite negb_true_iff.
+ destruct (q1 =? q2) ; intuition congruence.
+ - apply Z.leb_le.
+ - rewrite Z.geb_le. rewrite Z.ge_le_iff. tauto.
+ - apply Z.ltb_lt.
+ - rewrite <- Zgt_is_gt_bool; tauto.
+Qed.
+
+Definition Zeval_op2 (k: Tauto.kind) : Op2 -> Z -> Z -> Tauto.rtyp k:=
+ if k as k0 return (Op2 -> Z -> Z -> Tauto.rtyp k0)
+ then Zeval_pop2 else Zeval_bop2.
+
+
+Lemma Zeval_op2_hold : forall k op q1 q2,
+ Tauto.hold k (Zeval_op2 k op q1 q2) <-> Zeval_pop2 op q1 q2.
+Proof.
+ destruct k.
+ simpl ; tauto.
+ simpl. apply pop2_bop2.
+Qed.
+
+
+Definition Zeval_formula (env : PolEnv Z) (k: Tauto.kind) (f : Formula Z):=
let (lhs, op, rhs) := f in
- (Zeval_op2 op) (Zeval_expr env lhs) (Zeval_expr env rhs).
+ (Zeval_op2 k op) (Zeval_expr env lhs) (Zeval_expr env rhs).
Definition Zeval_formula' :=
eval_formula Z.add Z.mul Z.sub Z.opp (@eq Z) Z.le Z.lt (fun x => x) (fun x => x) (pow_N 1 Z.mul).
-Lemma Zeval_formula_compat' : forall env f, Zeval_formula env f <-> Zeval_formula' env f.
+Lemma Zeval_formula_compat : forall env k f, Tauto.hold k (Zeval_formula env k f) <-> Zeval_formula env Tauto.isProp f.
+Proof.
+ destruct k ; simpl.
+ - tauto.
+ - destruct f ; simpl.
+ rewrite <- Zeval_op2_hold with (k:=Tauto.isBool).
+ simpl. tauto.
+Qed.
+
+Lemma Zeval_formula_compat' : forall env f, Zeval_formula env Tauto.isProp f <-> Zeval_formula' env f.
Proof.
intros.
unfold Zeval_formula.
@@ -312,7 +360,7 @@ Definition xnnormalise (t : Formula Z) : NFormula Z :=
Lemma xnnormalise_correct :
forall env f,
- eval_nformula env (xnnormalise f) <-> Zeval_formula env f.
+ eval_nformula env (xnnormalise f) <-> Zeval_formula env Tauto.isProp f.
Proof.
intros.
rewrite Zeval_formula_compat'.
@@ -393,6 +441,7 @@ Proof.
Qed.
+
Require Import Coq.micromega.Tauto BinNums.
Definition cnf_of_list {T: Type} (tg : T) (l : list (NFormula Z)) :=
@@ -435,7 +484,7 @@ Definition normalise {T : Type} (t:Formula Z) (tg:T) : cnf (NFormula Z) T :=
if Zunsat f then cnf_ff _ _
else cnf_of_list tg (xnormalise f).
-Lemma normalise_correct : forall (T: Type) env t (tg:T), eval_cnf eval_nformula env (normalise t tg) <-> Zeval_formula env t.
+Lemma normalise_correct : forall (T: Type) env t (tg:T), eval_cnf eval_nformula env (normalise t tg) <-> Zeval_formula env Tauto.isProp t.
Proof.
intros.
rewrite <- xnnormalise_correct.
@@ -449,6 +498,7 @@ Proof.
apply xnormalise_correct.
Qed.
+
Definition xnegate (f:NFormula Z) : list (NFormula Z) :=
let (e,o) := f in
match o with
@@ -478,7 +528,7 @@ Proof.
- tauto.
Qed.
-Lemma negate_correct : forall T env t (tg:T), eval_cnf eval_nformula env (negate t tg) <-> ~ Zeval_formula env t.
+Lemma negate_correct : forall T env t (tg:T), eval_cnf eval_nformula env (negate t tg) <-> ~ Zeval_formula env Tauto.isProp t.
Proof.
intros.
rewrite <- xnnormalise_correct.
@@ -492,10 +542,10 @@ Proof.
apply xnegate_correct.
Qed.
-Definition cnfZ (Annot: Type) (TX : Type) (AF : Type) (f : TFormula (Formula Z) Annot TX AF) :=
+Definition cnfZ (Annot: Type) (TX : Tauto.kind -> Type) (AF : Type) (k: Tauto.kind) (f : TFormula (Formula Z) Annot TX AF k) :=
rxcnf Zunsat Zdeduce normalise negate true f.
-Definition ZweakTautoChecker (w: list ZWitness) (f : BFormula (Formula Z)) : bool :=
+Definition ZweakTautoChecker (w: list ZWitness) (f : BFormula (Formula Z) Tauto.isProp) : bool :=
@tauto_checker (Formula Z) (NFormula Z) unit Zunsat Zdeduce normalise negate ZWitness (fun cl => ZWeakChecker (List.map fst cl)) f w.
(* To get a complete checker, the proof format has to be enriched *)
@@ -1672,9 +1722,7 @@ Proof.
apply Nat.lt_succ_diag_r.
Qed.
-
-
-Definition ZTautoChecker (f : BFormula (Formula Z)) (w: list ZArithProof): bool :=
+Definition ZTautoChecker (f : BFormula (Formula Z) Tauto.isProp) (w: list ZArithProof): bool :=
@tauto_checker (Formula Z) (NFormula Z) unit Zunsat Zdeduce normalise negate ZArithProof (fun cl => ZChecker (List.map fst cl)) f w.
Lemma ZTautoChecker_sound : forall f w, ZTautoChecker f w = true -> forall env, eval_bf (Zeval_formula env) f.
@@ -1692,10 +1740,12 @@ Proof.
-
intros.
rewrite normalise_correct in H.
- auto.
+ rewrite Zeval_formula_compat; auto.
-
intros.
rewrite negate_correct in H ; auto.
+ rewrite Tauto.hold_eNOT.
+ rewrite Zeval_formula_compat; auto.
- intros t w0.
unfold eval_tt.
intros.
@@ -1703,8 +1753,6 @@ Proof.
eapply ZChecker_sound; eauto.
tauto.
Qed.
-
-
Fixpoint xhyps_of_pt (base:nat) (acc : list nat) (pt:ZArithProof) : list nat :=
match pt with
| DoneProof => acc
diff --git a/theories/micromega/ZifyBool.v b/theories/micromega/ZifyBool.v
index c693824f89..fa3f123b18 100644
--- a/theories/micromega/ZifyBool.v
+++ b/theories/micromega/ZifyBool.v
@@ -9,177 +9,83 @@
(************************************************************************)
Require Import Bool ZArith.
Require Import Zify ZifyClasses.
+Require Import ZifyInst.
Local Open Scope Z_scope.
-(* Instances of [ZifyClasses] for dealing with boolean operators.
- Various encodings of boolean are possible. One objective is to
- have an encoding that is terse but also lia friendly.
- *)
+(* Instances of [ZifyClasses] for dealing with boolean operators. *)
-(** [Z_of_bool] is the injection function for boolean *)
-Definition Z_of_bool (b : bool) : Z := if b then 1 else 0.
-
-(** [bool_of_Z] is a compatible reverse operation *)
-Definition bool_of_Z (z : Z) : bool := negb (Z.eqb z 0).
-
-Lemma Z_of_bool_bound : forall x, 0 <= Z_of_bool x <= 1.
-Proof.
- destruct x ; simpl; compute; intuition congruence.
-Qed.
-
-Instance Inj_bool_Z : InjTyp bool Z :=
- { inj := Z_of_bool ; pred :=(fun x => 0 <= x <= 1) ; cstr := Z_of_bool_bound}.
-Add InjTyp Inj_bool_Z.
+Instance Inj_bool_bool : InjTyp bool bool :=
+ { inj := (fun x => x) ; pred := (fun b => b = true \/ b = false) ;
+ cstr := (ltac:(intro b; destruct b; tauto))}.
+Add Zify InjTyp Inj_bool_bool.
(** Boolean operators *)
Instance Op_andb : BinOp andb :=
- { TBOp := Z.min ;
- TBOpInj := ltac: (destruct n,m; reflexivity)}.
-Add BinOp Op_andb.
+ { TBOp := andb ; TBOpInj := fun _ _ => eq_refl}.
+Add Zify BinOp Op_andb.
Instance Op_orb : BinOp orb :=
- { TBOp := Z.max ;
- TBOpInj := ltac:(destruct n,m; reflexivity)}.
-Add BinOp Op_orb.
+ { TBOp := orb ; TBOpInj := fun _ _ => eq_refl}.
+Add Zify BinOp Op_orb.
Instance Op_implb : BinOp implb :=
- { TBOp := fun x y => Z.max (1 - x) y;
- TBOpInj := ltac:(destruct n,m; reflexivity) }.
-Add BinOp Op_implb.
+ { TBOp := implb; TBOpInj := fun _ _ => eq_refl }.
+Add Zify BinOp Op_implb.
+
+Definition xorb_eq : forall b1 b2,
+ xorb b1 b2 = andb (orb b1 b2) (negb (eqb b1 b2)).
+Proof.
+ destruct b1,b2 ; reflexivity.
+Qed.
Instance Op_xorb : BinOp xorb :=
- { TBOp := fun x y => Z.max (x - y) (y - x);
- TBOpInj := ltac:(destruct n,m; reflexivity) }.
-Add BinOp Op_xorb.
+ { TBOp := fun x y => andb (orb x y) (negb (eqb x y)); TBOpInj := xorb_eq }.
+Add Zify BinOp Op_xorb.
+
+Instance Op_eqb : BinOp eqb :=
+ { TBOp := eqb; TBOpInj := fun _ _ => eq_refl }.
+Add Zify BinOp Op_eqb.
Instance Op_negb : UnOp negb :=
- { TUOp := fun x => 1 - x ; TUOpInj := ltac:(destruct x; reflexivity)}.
-Add UnOp Op_negb.
+ { TUOp := negb ; TUOpInj := fun _ => eq_refl}.
+Add Zify UnOp Op_negb.
Instance Op_eq_bool : BinRel (@eq bool) :=
- {TR := @eq Z ; TRInj := ltac:(destruct n,m; simpl ; intuition congruence) }.
-Add BinRel Op_eq_bool.
+ {TR := @eq bool ; TRInj := ltac:(reflexivity) }.
+Add Zify BinRel Op_eq_bool.
Instance Op_true : CstOp true :=
- { TCst := 1 ; TCstInj := eq_refl }.
-Add CstOp Op_true.
+ { TCst := true ; TCstInj := eq_refl }.
+Add Zify CstOp Op_true.
Instance Op_false : CstOp false :=
- { TCst := 0 ; TCstInj := eq_refl }.
-Add CstOp Op_false.
-
-(** Comparisons are encoded using the predicates [isZero] and [isLeZero].*)
-
-Definition isZero (z : Z) := Z_of_bool (Z.eqb z 0).
-
-Definition isLeZero (x : Z) := Z_of_bool (Z.leb x 0).
-
-Instance Op_isZero : UnOp isZero :=
- { TUOp := isZero; TUOpInj := ltac: (reflexivity) }.
-Add UnOp Op_isZero.
-
-Instance Op_isLeZero : UnOp isLeZero :=
- { TUOp := isLeZero; TUOpInj := ltac: (reflexivity) }.
-Add UnOp Op_isLeZero.
-
-(* Some intermediate lemma *)
-
-Lemma Z_eqb_isZero : forall n m,
- Z_of_bool (n =? m) = isZero (n - m).
-Proof.
- intros ; unfold isZero.
- destruct ( n =? m) eqn:EQ.
- - simpl. rewrite Z.eqb_eq in EQ.
- rewrite EQ. rewrite Z.sub_diag.
- reflexivity.
- -
- destruct (n - m =? 0) eqn:EQ'.
- rewrite Z.eqb_neq in EQ.
- rewrite Z.eqb_eq in EQ'.
- apply Zminus_eq in EQ'.
- congruence.
- reflexivity.
-Qed.
-
-Lemma Z_leb_sub : forall x y, x <=? y = ((x - y) <=? 0).
-Proof.
- intros.
- destruct (x <=?y) eqn:B1 ;
- destruct (x - y <=?0) eqn:B2 ; auto.
- - rewrite Z.leb_le in B1.
- rewrite Z.leb_nle in B2.
- rewrite Z.le_sub_0 in B2. tauto.
- - rewrite Z.leb_nle in B1.
- rewrite Z.leb_le in B2.
- rewrite Z.le_sub_0 in B2. tauto.
-Qed.
-
-Lemma Z_ltb_leb : forall x y, x <? y = (x +1 <=? y).
-Proof.
- intros.
- destruct (x <?y) eqn:B1 ;
- destruct (x + 1 <=?y) eqn:B2 ; auto.
- - rewrite Z.ltb_lt in B1.
- rewrite Z.leb_nle in B2.
- apply Zorder.Zlt_le_succ in B1.
- unfold Z.succ in B1.
- tauto.
- - rewrite Z.ltb_nlt in B1.
- rewrite Z.leb_le in B2.
- apply Zorder.Zle_lt_succ in B2.
- unfold Z.succ in B2.
- apply Zorder.Zplus_lt_reg_r in B2.
- tauto.
-Qed.
-
+ { TCst := false ; TCstInj := eq_refl }.
+Add Zify CstOp Op_false.
(** Comparison over Z *)
Instance Op_Zeqb : BinOp Z.eqb :=
- { TBOp := fun x y => isZero (Z.sub x y) ; TBOpInj := Z_eqb_isZero}.
+ { TBOp := Z.eqb ; TBOpInj := fun _ _ => eq_refl }.
+Add Zify BinOp Op_Zeqb.
Instance Op_Zleb : BinOp Z.leb :=
- { TBOp := fun x y => isLeZero (x-y) ;
- TBOpInj :=
- ltac: (intros;unfold isLeZero;
- rewrite Z_leb_sub;
- auto) }.
-Add BinOp Op_Zleb.
+ { TBOp := Z.leb; TBOpInj := fun _ _ => eq_refl }.
+Add Zify BinOp Op_Zleb.
Instance Op_Zgeb : BinOp Z.geb :=
- { TBOp := fun x y => isLeZero (y-x) ;
- TBOpInj := ltac:(
- intros;
- unfold isLeZero;
- rewrite Z.geb_leb;
- rewrite Z_leb_sub;
- auto) }.
-Add BinOp Op_Zgeb.
+ { TBOp := Z.geb; TBOpInj := fun _ _ => eq_refl }.
+Add Zify BinOp Op_Zgeb.
Instance Op_Zltb : BinOp Z.ltb :=
- { TBOp := fun x y => isLeZero (x+1-y) ;
- TBOpInj := ltac:(
- intros;
- unfold isLeZero;
- rewrite Z_ltb_leb;
- rewrite <- Z_leb_sub;
- reflexivity) }.
+ { TBOp := Z.ltb ; TBOpInj := fun _ _ => eq_refl }.
+Add Zify BinOp Op_Zltb.
Instance Op_Zgtb : BinOp Z.gtb :=
- { TBOp := fun x y => isLeZero (y-x+1) ;
- TBOpInj := ltac:(
- intros;
- unfold isLeZero;
- rewrite Z.gtb_ltb;
- rewrite Z_ltb_leb;
- rewrite Z_leb_sub;
- rewrite Z.add_sub_swap;
- reflexivity) }.
-Add BinOp Op_Zgtb.
+ { TBOp := Z.gtb; TBOpInj := fun _ _ => eq_refl }.
+Add Zify BinOp Op_Zgtb.
(** Comparison over nat *)
-
Lemma Z_of_nat_eqb_iff : forall n m,
(n =? m)%nat = (Z.of_nat n =? Z.of_nat m).
Proof.
@@ -211,68 +117,45 @@ Proof.
Qed.
Instance Op_nat_eqb : BinOp Nat.eqb :=
- { TBOp := fun x y => isZero (Z.sub x y) ;
- TBOpInj := ltac:(
- intros; simpl;
- rewrite <- Z_eqb_isZero;
- f_equal; apply Z_of_nat_eqb_iff) }.
-Add BinOp Op_nat_eqb.
+ { TBOp := Z.eqb; TBOpInj := Z_of_nat_eqb_iff }.
+Add Zify BinOp Op_nat_eqb.
Instance Op_nat_leb : BinOp Nat.leb :=
- { TBOp := fun x y => isLeZero (x-y) ;
- TBOpInj := ltac:(
- intros;
- rewrite Z_of_nat_leb_iff;
- unfold isLeZero;
- rewrite Z_leb_sub;
- auto) }.
-Add BinOp Op_nat_leb.
+ { TBOp := Z.leb; TBOpInj := Z_of_nat_leb_iff }.
+Add Zify BinOp Op_nat_leb.
Instance Op_nat_ltb : BinOp Nat.ltb :=
- { TBOp := fun x y => isLeZero (x+1-y) ;
- TBOpInj := ltac:(
- intros;
- rewrite Z_of_nat_ltb_iff;
- unfold isLeZero;
- rewrite Z_ltb_leb;
- rewrite <- Z_leb_sub;
- reflexivity) }.
-Add BinOp Op_nat_ltb.
-
-(** Injected boolean operators *)
-
-Lemma Z_eqb_ZSpec_ok : forall x, 0 <= isZero x <= 1 /\
- (x = 0 <-> isZero x = 1).
+ { TBOp := Z.ltb; TBOpInj := Z_of_nat_ltb_iff }.
+Add Zify BinOp Op_nat_ltb.
+
+Lemma b2n_b2z : forall x, Z.of_nat (Nat.b2n x) = Z.b2z x.
Proof.
- intros.
- unfold isZero.
- destruct (x =? 0) eqn:EQ.
- - apply Z.eqb_eq in EQ.
- simpl. intuition try congruence;
- compute ; congruence.
- - apply Z.eqb_neq in EQ.
- simpl. intuition try congruence;
- compute ; congruence.
+ intro. destruct x ; reflexivity.
Qed.
+Instance Op_b2n : UnOp Nat.b2n :=
+ { TUOp := Z.b2z; TUOpInj := b2n_b2z }.
+Add Zify UnOp Op_b2n.
-Instance Z_eqb_ZSpec : UnOpSpec isZero :=
- {| UPred := fun n r => 0 <= r <= 1 /\ (n = 0 <-> isZero n = 1) ; USpec := Z_eqb_ZSpec_ok |}.
-Add Spec Z_eqb_ZSpec.
+Instance Op_b2z : UnOp Z.b2z :=
+ { TUOp := Z.b2z; TUOpInj := fun _ => eq_refl }.
+Add Zify UnOp Op_b2z.
-Lemma leZeroSpec_ok : forall x, x <= 0 /\ isLeZero x = 1 \/ x > 0 /\ isLeZero x = 0.
+Lemma b2z_spec : forall b, (b = true /\ Z.b2z b = 1) \/ (b = false /\ Z.b2z b = 0).
Proof.
- intros.
- unfold isLeZero.
- destruct (x <=? 0) eqn:EQ.
- - apply Z.leb_le in EQ.
- simpl. intuition congruence.
- - simpl.
- apply Z.leb_nle in EQ.
- apply Zorder.Znot_le_gt in EQ.
- tauto.
+ destruct b ; simpl; intuition congruence.
Qed.
-Instance leZeroSpec : UnOpSpec isLeZero :=
- {| UPred := fun n r => (n<=0 /\ r = 1) \/ (n > 0 /\ r = 0) ; USpec := leZeroSpec_ok|}.
-Add Spec leZeroSpec.
+Instance b2zSpec : UnOpSpec Z.b2z :=
+ { UPred := fun b r => (b = true /\ r = 1) \/ (b = false /\ r = 0);
+ USpec := b2z_spec
+ }.
+Add Zify UnOpSpec b2zSpec.
+
+Ltac elim_bool_cstr :=
+ repeat match goal with
+ | C : ?B = true \/ ?B = false |- _ =>
+ destruct C as [C|C]; rewrite C in *
+ end.
+
+Ltac Zify.zify_post_hook ::= elim_bool_cstr.
diff --git a/theories/micromega/ZifyClasses.v b/theories/micromega/ZifyClasses.v
index 3eb4c924ae..37eef12381 100644
--- a/theories/micromega/ZifyClasses.v
+++ b/theories/micromega/ZifyClasses.v
@@ -34,19 +34,19 @@ Class InjTyp (S : Type) (T : Type) :=
(** [BinOp Op] declares a source operator [Op: S1 -> S2 -> S3].
*)
-Class BinOp {S1 S2 S3:Type} {T:Type} (Op : S1 -> S2 -> S3) {I1 : InjTyp S1 T} {I2 : InjTyp S2 T} {I3 : InjTyp S3 T} :=
+Class BinOp {S1 S2 S3 T1 T2 T3:Type} (Op : S1 -> S2 -> S3) {I1 : InjTyp S1 T1} {I2 : InjTyp S2 T2} {I3 : InjTyp S3 T3} :=
mkbop {
(* [TBOp] is the target operator after injection of operands. *)
- TBOp : T -> T -> T;
+ TBOp : T1 -> T2 -> T3;
(* [TBOpInj] states the correctness of the injection. *)
TBOpInj : forall (n:S1) (m:S2), inj (Op n m) = TBOp (inj n) (inj m)
}.
(** [Unop Op] declares a source operator [Op : S1 -> S2]. *)
-Class UnOp {S1 S2 T:Type} (Op : S1 -> S2) {I1 : InjTyp S1 T} {I2 : InjTyp S2 T} :=
+Class UnOp {S1 S2 T1 T2:Type} (Op : S1 -> S2) {I1 : InjTyp S1 T1} {I2 : InjTyp S2 T2} :=
mkuop {
(* [TUOp] is the target operator after injection of operands. *)
- TUOp : T -> T;
+ TUOp : T1 -> T2;
(* [TUOpInj] states the correctness of the injection. *)
TUOpInj : forall (x:S1), inj (Op x) = TUOp (inj x)
}.
@@ -90,15 +90,15 @@ Class PropUOp (Op : Prop -> Prop) :=
NB1: The Ltac code is currently limited to (Op: Z -> Z -> Z)
NB2: This is not sufficient to cope with [Z.div] or [Z.mod]
*)
-Class BinOpSpec {S T: Type} (Op : T -> T -> T) {I : InjTyp S T} :=
+Class BinOpSpec {T1 T2 T3: Type} (Op : T1 -> T2 -> T3) :=
mkbspec {
- BPred : T -> T -> T -> Prop;
+ BPred : T1 -> T2 -> T3 -> Prop;
BSpec : forall x y, BPred x y (Op x y)
}.
-Class UnOpSpec {S T: Type} (Op : T -> T) {I : InjTyp S T} :=
+Class UnOpSpec {T1 T2: Type} (Op : T1 -> T2) :=
mkuspec {
- UPred : T -> T -> Prop;
+ UPred : T1 -> T2 -> Prop;
USpec : forall x, UPred x (Op x)
}.
@@ -141,9 +141,6 @@ Record injprop :=
injprop_ok : source_prop <-> target_prop}.
-
-
-
(** Lemmas for building rewrite rules. *)
Definition PropOp_iff (Op : Prop -> Prop -> Prop) :=
@@ -152,22 +149,22 @@ Definition PropOp_iff (Op : Prop -> Prop -> Prop) :=
Definition PropUOp_iff (Op : Prop -> Prop) :=
forall (p1 q1 :Prop), (p1 <-> q1) -> (Op p1 <-> Op q1).
-Lemma mkapp2 (S1 S2 S3 T : Type) (Op : S1 -> S2 -> S3)
- (I1 : S1 -> T) (I2 : S2 -> T) (I3 : S3 -> T)
- (TBOP : T -> T -> T)
+Lemma mkapp2 (S1 S2 S3 T1 T2 T3 : Type) (Op : S1 -> S2 -> S3)
+ (I1 : S1 -> T1) (I2 : S2 -> T2) (I3 : S3 -> T3)
+ (TBOP : T1 -> T2 -> T3)
(TBOPINJ : forall n m, I3 (Op n m) = TBOP (I1 n) (I2 m))
- (s1 : S1) (t1 : T) (P1: I1 s1 = t1)
- (s2 : S2) (t2 : T) (P2: I2 s2 = t2): I3 (Op s1 s2) = TBOP t1 t2.
+ (s1 : S1) (t1 : T1) (P1: I1 s1 = t1)
+ (s2 : S2) (t2 : T2) (P2: I2 s2 = t2): I3 (Op s1 s2) = TBOP t1 t2.
Proof.
subst. apply TBOPINJ.
Qed.
-Lemma mkapp (S1 S2 T : Type) (OP : S1 -> S2)
- (I1 : S1 -> T)
- (I2 : S2 -> T)
- (TUOP : T -> T)
+Lemma mkapp (S1 S2 T1 T2 : Type) (OP : S1 -> S2)
+ (I1 : S1 -> T1)
+ (I2 : S2 -> T2)
+ (TUOP : T1 -> T2)
(TUOPINJ : forall n, I2 (OP n) = TUOP (I1 n))
- (s1: S1) (t1: T) (P1: I1 s1 = t1): I2 (OP s1) = TUOP t1.
+ (s1: S1) (t1: T1) (P1: I1 s1 = t1): I2 (OP s1) = TUOP t1.
Proof.
subst. apply TUOPINJ.
Qed.
@@ -223,8 +220,6 @@ Proof.
exact (fun H => proj1 IFF H).
Qed.
-Definition identity (A : Type) : A -> A := fun x => x.
-
(** Registering constants for use by the plugin *)
Register eq_iff as ZifyClasses.eq_iff.
Register target_prop as ZifyClasses.target_prop.
@@ -268,6 +263,4 @@ Register iff_morph as ZifyClasses.iff_morph.
Register impl_morph as ZifyClasses.impl_morph.
Register not as ZifyClasses.not.
Register not_morph as ZifyClasses.not_morph.
-
-(** Identify function *)
-Register identity as ZifyClasses.identity.
+Register True as ZifyClasses.True.
diff --git a/theories/micromega/ZifyComparison.v b/theories/micromega/ZifyComparison.v
index 9b37f10841..a4ada571f1 100644
--- a/theories/micromega/ZifyComparison.v
+++ b/theories/micromega/ZifyComparison.v
@@ -28,30 +28,30 @@ Qed.
Instance Inj_comparison_Z : InjTyp comparison Z :=
{ inj := Z_of_comparison ; pred :=(fun x => -1 <= x <= 1) ; cstr := Z_of_comparison_bound}.
-Add InjTyp Inj_comparison_Z.
+Add Zify InjTyp Inj_comparison_Z.
Definition ZcompareZ (x y : Z) :=
Z_of_comparison (Z.compare x y).
Program Instance BinOp_Zcompare : BinOp Z.compare :=
{ TBOp := ZcompareZ }.
-Add BinOp BinOp_Zcompare.
+Add Zify BinOp BinOp_Zcompare.
Instance Op_eq_comparison : BinRel (@eq comparison) :=
{TR := @eq Z ; TRInj := ltac:(destruct n,m; simpl ; intuition congruence) }.
-Add BinRel Op_eq_comparison.
+Add Zify BinRel Op_eq_comparison.
Instance Op_Eq : CstOp Eq :=
{ TCst := 0 ; TCstInj := eq_refl }.
-Add CstOp Op_Eq.
+Add Zify CstOp Op_Eq.
Instance Op_Lt : CstOp Lt :=
{ TCst := -1 ; TCstInj := eq_refl }.
-Add CstOp Op_Lt.
+Add Zify CstOp Op_Lt.
Instance Op_Gt : CstOp Gt :=
{ TCst := 1 ; TCstInj := eq_refl }.
-Add CstOp Op_Gt.
+Add Zify CstOp Op_Gt.
Lemma Zcompare_spec : forall x y,
@@ -79,4 +79,4 @@ Instance ZcompareSpec : BinOpSpec ZcompareZ :=
/\
(x < y -> r = -1)
; BSpec := Zcompare_spec|}.
-Add Spec ZcompareSpec.
+Add Zify BinOpSpec ZcompareSpec.
diff --git a/theories/micromega/ZifyInst.v b/theories/micromega/ZifyInst.v
index 5b15dc072a..0e135ba793 100644
--- a/theories/micromega/ZifyInst.v
+++ b/theories/micromega/ZifyInst.v
@@ -25,117 +25,117 @@ Ltac refl :=
Instance Inj_Z_Z : InjTyp Z Z :=
mkinj _ _ (fun x => x) (fun x => True ) (fun _ => I).
-Add InjTyp Inj_Z_Z.
+Add Zify InjTyp Inj_Z_Z.
(** Support for nat *)
Instance Inj_nat_Z : InjTyp nat Z :=
mkinj _ _ Z.of_nat (fun x => 0 <= x ) Nat2Z.is_nonneg.
-Add InjTyp Inj_nat_Z.
+Add Zify InjTyp Inj_nat_Z.
(* zify_nat_rel *)
Instance Op_ge : BinRel ge :=
{| TR := Z.ge; TRInj := Nat2Z.inj_ge |}.
-Add BinRel Op_ge.
+Add Zify BinRel Op_ge.
Instance Op_lt : BinRel lt :=
{| TR := Z.lt; TRInj := Nat2Z.inj_lt |}.
-Add BinRel Op_lt.
+Add Zify BinRel Op_lt.
Instance Op_Nat_lt : BinRel Nat.lt := Op_lt.
-Add BinRel Op_Nat_lt.
+Add Zify BinRel Op_Nat_lt.
Instance Op_gt : BinRel gt :=
{| TR := Z.gt; TRInj := Nat2Z.inj_gt |}.
-Add BinRel Op_gt.
+Add Zify BinRel Op_gt.
Instance Op_le : BinRel le :=
{| TR := Z.le; TRInj := Nat2Z.inj_le |}.
-Add BinRel Op_le.
+Add Zify BinRel Op_le.
Instance Op_Nat_le : BinRel Nat.le := Op_le.
-Add BinRel Op_Nat_le.
+Add Zify BinRel Op_Nat_le.
Instance Op_eq_nat : BinRel (@eq nat) :=
{| TR := @eq Z ; TRInj := fun x y : nat => iff_sym (Nat2Z.inj_iff x y) |}.
-Add BinRel Op_eq_nat.
+Add Zify BinRel Op_eq_nat.
Instance Op_Nat_eq : BinRel (Nat.eq) := Op_eq_nat.
-Add BinRel Op_Nat_eq.
+Add Zify BinRel Op_Nat_eq.
(* zify_nat_op *)
Instance Op_plus : BinOp Nat.add :=
{| TBOp := Z.add; TBOpInj := Nat2Z.inj_add |}.
-Add BinOp Op_plus.
+Add Zify BinOp Op_plus.
Instance Op_sub : BinOp Nat.sub :=
{| TBOp := fun n m => Z.max 0 (n - m) ; TBOpInj := Nat2Z.inj_sub_max |}.
-Add BinOp Op_sub.
+Add Zify BinOp Op_sub.
Instance Op_mul : BinOp Nat.mul :=
{| TBOp := Z.mul ; TBOpInj := Nat2Z.inj_mul |}.
-Add BinOp Op_mul.
+Add Zify BinOp Op_mul.
Instance Op_min : BinOp Nat.min :=
{| TBOp := Z.min ; TBOpInj := Nat2Z.inj_min |}.
-Add BinOp Op_min.
+Add Zify BinOp Op_min.
Instance Op_max : BinOp Nat.max :=
{| TBOp := Z.max ; TBOpInj := Nat2Z.inj_max |}.
-Add BinOp Op_max.
+Add Zify BinOp Op_max.
Instance Op_pred : UnOp Nat.pred :=
{| TUOp := fun n => Z.max 0 (n - 1) ; TUOpInj := Nat2Z.inj_pred_max |}.
-Add UnOp Op_pred.
+Add Zify UnOp Op_pred.
Instance Op_S : UnOp S :=
{| TUOp := fun x => Z.add x 1 ; TUOpInj := Nat2Z.inj_succ |}.
-Add UnOp Op_S.
+Add Zify UnOp Op_S.
Instance Op_O : CstOp O :=
{| TCst := Z0 ; TCstInj := eq_refl (Z.of_nat 0) |}.
-Add CstOp Op_O.
+Add Zify CstOp Op_O.
Instance Op_Z_abs_nat : UnOp Z.abs_nat :=
{ TUOp := Z.abs ; TUOpInj := Zabs2Nat.id_abs }.
-Add UnOp Op_Z_abs_nat.
+Add Zify UnOp Op_Z_abs_nat.
(** Support for positive *)
Instance Inj_pos_Z : InjTyp positive Z :=
{| inj := Zpos ; pred := (fun x => 0 < x ) ; cstr := Pos2Z.pos_is_pos |}.
-Add InjTyp Inj_pos_Z.
+Add Zify InjTyp Inj_pos_Z.
Instance Op_pos_to_nat : UnOp Pos.to_nat :=
{TUOp := (fun x => x); TUOpInj := positive_nat_Z}.
-Add UnOp Op_pos_to_nat.
+Add Zify UnOp Op_pos_to_nat.
Instance Inj_N_Z : InjTyp N Z :=
mkinj _ _ Z.of_N (fun x => 0 <= x ) N2Z.is_nonneg.
-Add InjTyp Inj_N_Z.
+Add Zify InjTyp Inj_N_Z.
Instance Op_N_to_nat : UnOp N.to_nat :=
{ TUOp := fun x => x ; TUOpInj := N_nat_Z }.
-Add UnOp Op_N_to_nat.
+Add Zify UnOp Op_N_to_nat.
(* zify_positive_rel *)
Instance Op_pos_ge : BinRel Pos.ge :=
{| TR := Z.ge; TRInj := fun x y => iff_refl (Z.pos x >= Z.pos y) |}.
-Add BinRel Op_pos_ge.
+Add Zify BinRel Op_pos_ge.
Instance Op_pos_lt : BinRel Pos.lt :=
{| TR := Z.lt; TRInj := fun x y => iff_refl (Z.pos x < Z.pos y) |}.
-Add BinRel Op_pos_lt.
+Add Zify BinRel Op_pos_lt.
Instance Op_pos_gt : BinRel Pos.gt :=
{| TR := Z.gt; TRInj := fun x y => iff_refl (Z.pos x > Z.pos y) |}.
-Add BinRel Op_pos_gt.
+Add Zify BinRel Op_pos_gt.
Instance Op_pos_le : BinRel Pos.le :=
{| TR := Z.le; TRInj := fun x y => iff_refl (Z.pos x <= Z.pos y) |}.
-Add BinRel Op_pos_le.
+Add Zify BinRel Op_pos_le.
Lemma eq_pos_inj : forall (x y:positive), x = y <-> Z.pos x = Z.pos y.
Proof.
@@ -145,36 +145,36 @@ Qed.
Instance Op_eq_pos : BinRel (@eq positive) :=
{ TR := @eq Z ; TRInj := eq_pos_inj }.
-Add BinRel Op_eq_pos.
+Add Zify BinRel Op_eq_pos.
(* zify_positive_op *)
Instance Op_Z_of_N : UnOp Z.of_N :=
{ TUOp := (fun x => x) ; TUOpInj := fun x => eq_refl (Z.of_N x) }.
-Add UnOp Op_Z_of_N.
+Add Zify UnOp Op_Z_of_N.
Instance Op_Z_to_N : UnOp Z.to_N :=
{ TUOp := fun x => Z.max 0 x ; TUOpInj := ltac:(now intro x; destruct x) }.
-Add UnOp Op_Z_to_N.
+Add Zify UnOp Op_Z_to_N.
Instance Op_Z_neg : UnOp Z.neg :=
{ TUOp := Z.opp ; TUOpInj := (fun x => eq_refl (Zneg x))}.
-Add UnOp Op_Z_neg.
+Add Zify UnOp Op_Z_neg.
Instance Op_Z_pos : UnOp Z.pos :=
{ TUOp := (fun x => x) ; TUOpInj := (fun x => eq_refl (Z.pos x))}.
-Add UnOp Op_Z_pos.
+Add Zify UnOp Op_Z_pos.
Instance Op_pos_succ : UnOp Pos.succ :=
{ TUOp := fun x => x + 1; TUOpInj := Pos2Z.inj_succ }.
-Add UnOp Op_pos_succ.
+Add Zify UnOp Op_pos_succ.
Instance Op_pos_pred_double : UnOp Pos.pred_double :=
{ TUOp := fun x => 2 * x - 1; TUOpInj := ltac:(refl) }.
-Add UnOp Op_pos_pred_double.
+Add Zify UnOp Op_pos_pred_double.
Instance Op_pos_pred : UnOp Pos.pred :=
{ TUOp := fun x => Z.max 1 (x - 1) ;
@@ -182,266 +182,266 @@ Instance Op_pos_pred : UnOp Pos.pred :=
(intros;
rewrite <- Pos.sub_1_r;
apply Pos2Z.inj_sub_max) }.
-Add UnOp Op_pos_pred.
+Add Zify UnOp Op_pos_pred.
Instance Op_pos_predN : UnOp Pos.pred_N :=
{ TUOp := fun x => x - 1 ;
TUOpInj := ltac: (now destruct x; rewrite N.pos_pred_spec) }.
-Add UnOp Op_pos_predN.
+Add Zify UnOp Op_pos_predN.
Instance Op_pos_of_succ_nat : UnOp Pos.of_succ_nat :=
{ TUOp := fun x => x + 1 ; TUOpInj := Zpos_P_of_succ_nat }.
-Add UnOp Op_pos_of_succ_nat.
+Add Zify UnOp Op_pos_of_succ_nat.
Instance Op_pos_of_nat : UnOp Pos.of_nat :=
{ TUOp := fun x => Z.max 1 x ;
TUOpInj := ltac: (now destruct x;
[|rewrite <- Pos.of_nat_succ, <- (Nat2Z.inj_max 1)]) }.
-Add UnOp Op_pos_of_nat.
+Add Zify UnOp Op_pos_of_nat.
Instance Op_pos_add : BinOp Pos.add :=
{ TBOp := Z.add ; TBOpInj := ltac: (refl) }.
-Add BinOp Op_pos_add.
+Add Zify BinOp Op_pos_add.
Instance Op_pos_add_carry : BinOp Pos.add_carry :=
{ TBOp := fun x y => x + y + 1 ;
TBOpInj := ltac:(now intros; rewrite Pos.add_carry_spec, Pos2Z.inj_succ) }.
-Add BinOp Op_pos_add_carry.
+Add Zify BinOp Op_pos_add_carry.
Instance Op_pos_sub : BinOp Pos.sub :=
{ TBOp := fun n m => Z.max 1 (n - m) ;TBOpInj := Pos2Z.inj_sub_max }.
-Add BinOp Op_pos_sub.
+Add Zify BinOp Op_pos_sub.
Instance Op_pos_mul : BinOp Pos.mul :=
{ TBOp := Z.mul ; TBOpInj := ltac: (refl) }.
-Add BinOp Op_pos_mul.
+Add Zify BinOp Op_pos_mul.
Instance Op_pos_min : BinOp Pos.min :=
{ TBOp := Z.min ; TBOpInj := Pos2Z.inj_min }.
-Add BinOp Op_pos_min.
+Add Zify BinOp Op_pos_min.
Instance Op_pos_max : BinOp Pos.max :=
{ TBOp := Z.max ; TBOpInj := Pos2Z.inj_max }.
-Add BinOp Op_pos_max.
+Add Zify BinOp Op_pos_max.
Instance Op_pos_pow : BinOp Pos.pow :=
{ TBOp := Z.pow ; TBOpInj := Pos2Z.inj_pow }.
-Add BinOp Op_pos_pow.
+Add Zify BinOp Op_pos_pow.
Instance Op_pos_square : UnOp Pos.square :=
{ TUOp := Z.square ; TUOpInj := Pos2Z.inj_square }.
-Add UnOp Op_pos_square.
+Add Zify UnOp Op_pos_square.
Instance Op_xO : UnOp xO :=
{ TUOp := fun x => 2 * x ; TUOpInj := ltac: (refl) }.
-Add UnOp Op_xO.
+Add Zify UnOp Op_xO.
Instance Op_xI : UnOp xI :=
{ TUOp := fun x => 2 * x + 1 ; TUOpInj := ltac: (refl) }.
-Add UnOp Op_xI.
+Add Zify UnOp Op_xI.
Instance Op_xH : CstOp xH :=
{ TCst := 1%Z ; TCstInj := ltac:(refl)}.
-Add CstOp Op_xH.
+Add Zify CstOp Op_xH.
Instance Op_Z_of_nat : UnOp Z.of_nat:=
{ TUOp := fun x => x ; TUOpInj := (fun x : nat => @eq_refl Z (Z.of_nat x)) }.
-Add UnOp Op_Z_of_nat.
+Add Zify UnOp Op_Z_of_nat.
(* zify_N_rel *)
Instance Op_N_ge : BinRel N.ge :=
{| TR := Z.ge ; TRInj := N2Z.inj_ge |}.
-Add BinRel Op_N_ge.
+Add Zify BinRel Op_N_ge.
Instance Op_N_lt : BinRel N.lt :=
{| TR := Z.lt ; TRInj := N2Z.inj_lt |}.
-Add BinRel Op_N_lt.
+Add Zify BinRel Op_N_lt.
Instance Op_N_gt : BinRel N.gt :=
{| TR := Z.gt ; TRInj := N2Z.inj_gt |}.
-Add BinRel Op_N_gt.
+Add Zify BinRel Op_N_gt.
Instance Op_N_le : BinRel N.le :=
{| TR := Z.le ; TRInj := N2Z.inj_le |}.
-Add BinRel Op_N_le.
+Add Zify BinRel Op_N_le.
Instance Op_eq_N : BinRel (@eq N) :=
{| TR := @eq Z ; TRInj := fun x y : N => iff_sym (N2Z.inj_iff x y) |}.
-Add BinRel Op_eq_N.
+Add Zify BinRel Op_eq_N.
(* zify_N_op *)
Instance Op_N_N0 : CstOp N0 :=
{ TCst := Z0 ; TCstInj := eq_refl }.
-Add CstOp Op_N_N0.
+Add Zify CstOp Op_N_N0.
Instance Op_N_Npos : UnOp Npos :=
{ TUOp := (fun x => x) ; TUOpInj := ltac:(refl) }.
-Add UnOp Op_N_Npos.
+Add Zify UnOp Op_N_Npos.
Instance Op_N_of_nat : UnOp N.of_nat :=
{ TUOp := fun x => x ; TUOpInj := nat_N_Z }.
-Add UnOp Op_N_of_nat.
+Add Zify UnOp Op_N_of_nat.
Instance Op_Z_abs_N : UnOp Z.abs_N :=
{ TUOp := Z.abs ; TUOpInj := N2Z.inj_abs_N }.
-Add UnOp Op_Z_abs_N.
+Add Zify UnOp Op_Z_abs_N.
Instance Op_N_pos : UnOp N.pos :=
{ TUOp := fun x => x ; TUOpInj := ltac:(refl)}.
-Add UnOp Op_N_pos.
+Add Zify UnOp Op_N_pos.
Instance Op_N_add : BinOp N.add :=
{| TBOp := Z.add ; TBOpInj := N2Z.inj_add |}.
-Add BinOp Op_N_add.
+Add Zify BinOp Op_N_add.
Instance Op_N_min : BinOp N.min :=
{| TBOp := Z.min ; TBOpInj := N2Z.inj_min |}.
-Add BinOp Op_N_min.
+Add Zify BinOp Op_N_min.
Instance Op_N_max : BinOp N.max :=
{| TBOp := Z.max ; TBOpInj := N2Z.inj_max |}.
-Add BinOp Op_N_max.
+Add Zify BinOp Op_N_max.
Instance Op_N_mul : BinOp N.mul :=
{| TBOp := Z.mul ; TBOpInj := N2Z.inj_mul |}.
-Add BinOp Op_N_mul.
+Add Zify BinOp Op_N_mul.
Instance Op_N_sub : BinOp N.sub :=
{| TBOp := fun x y => Z.max 0 (x - y) ; TBOpInj := N2Z.inj_sub_max|}.
-Add BinOp Op_N_sub.
+Add Zify BinOp Op_N_sub.
Instance Op_N_div : BinOp N.div :=
{| TBOp := Z.div ; TBOpInj := N2Z.inj_div|}.
-Add BinOp Op_N_div.
+Add Zify BinOp Op_N_div.
Instance Op_N_mod : BinOp N.modulo :=
{| TBOp := Z.rem ; TBOpInj := N2Z.inj_rem|}.
-Add BinOp Op_N_mod.
+Add Zify BinOp Op_N_mod.
Instance Op_N_pred : UnOp N.pred :=
{ TUOp := fun x => Z.max 0 (x - 1) ;
TUOpInj :=
ltac:(intros; rewrite N.pred_sub; apply N2Z.inj_sub_max) }.
-Add UnOp Op_N_pred.
+Add Zify UnOp Op_N_pred.
Instance Op_N_succ : UnOp N.succ :=
{| TUOp := fun x => x + 1 ; TUOpInj := N2Z.inj_succ |}.
-Add UnOp Op_N_succ.
+Add Zify UnOp Op_N_succ.
(** Support for Z - injected to itself *)
(* zify_Z_rel *)
Instance Op_Z_ge : BinRel Z.ge :=
{| TR := Z.ge ; TRInj := fun x y => iff_refl (x>= y)|}.
-Add BinRel Op_Z_ge.
+Add Zify BinRel Op_Z_ge.
Instance Op_Z_lt : BinRel Z.lt :=
{| TR := Z.lt ; TRInj := fun x y => iff_refl (x < y)|}.
-Add BinRel Op_Z_lt.
+Add Zify BinRel Op_Z_lt.
Instance Op_Z_gt : BinRel Z.gt :=
{| TR := Z.gt ;TRInj := fun x y => iff_refl (x > y)|}.
-Add BinRel Op_Z_gt.
+Add Zify BinRel Op_Z_gt.
Instance Op_Z_le : BinRel Z.le :=
{| TR := Z.le ;TRInj := fun x y => iff_refl (x <= y)|}.
-Add BinRel Op_Z_le.
+Add Zify BinRel Op_Z_le.
Instance Op_eqZ : BinRel (@eq Z) :=
{ TR := @eq Z ; TRInj := fun x y => iff_refl (x = y) }.
-Add BinRel Op_eqZ.
+Add Zify BinRel Op_eqZ.
Instance Op_Z_Z0 : CstOp Z0 :=
{ TCst := Z0 ; TCstInj := eq_refl }.
-Add CstOp Op_Z_Z0.
+Add Zify CstOp Op_Z_Z0.
Instance Op_Z_add : BinOp Z.add :=
{ TBOp := Z.add ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_add.
+Add Zify BinOp Op_Z_add.
Instance Op_Z_min : BinOp Z.min :=
{ TBOp := Z.min ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_min.
+Add Zify BinOp Op_Z_min.
Instance Op_Z_max : BinOp Z.max :=
{ TBOp := Z.max ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_max.
+Add Zify BinOp Op_Z_max.
Instance Op_Z_mul : BinOp Z.mul :=
{ TBOp := Z.mul ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_mul.
+Add Zify BinOp Op_Z_mul.
Instance Op_Z_sub : BinOp Z.sub :=
{ TBOp := Z.sub ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_sub.
+Add Zify BinOp Op_Z_sub.
Instance Op_Z_div : BinOp Z.div :=
{ TBOp := Z.div ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_div.
+Add Zify BinOp Op_Z_div.
Instance Op_Z_mod : BinOp Z.modulo :=
{ TBOp := Z.modulo ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_mod.
+Add Zify BinOp Op_Z_mod.
Instance Op_Z_rem : BinOp Z.rem :=
{ TBOp := Z.rem ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_rem.
+Add Zify BinOp Op_Z_rem.
Instance Op_Z_quot : BinOp Z.quot :=
{ TBOp := Z.quot ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_quot.
+Add Zify BinOp Op_Z_quot.
Instance Op_Z_succ : UnOp Z.succ :=
{ TUOp := fun x => x + 1 ; TUOpInj := ltac:(refl) }.
-Add UnOp Op_Z_succ.
+Add Zify UnOp Op_Z_succ.
Instance Op_Z_pred : UnOp Z.pred :=
{ TUOp := fun x => x - 1 ; TUOpInj := ltac:(refl) }.
-Add UnOp Op_Z_pred.
+Add Zify UnOp Op_Z_pred.
Instance Op_Z_opp : UnOp Z.opp :=
{ TUOp := Z.opp ; TUOpInj := ltac:(refl) }.
-Add UnOp Op_Z_opp.
+Add Zify UnOp Op_Z_opp.
Instance Op_Z_abs : UnOp Z.abs :=
{ TUOp := Z.abs ; TUOpInj := ltac:(refl) }.
-Add UnOp Op_Z_abs.
+Add Zify UnOp Op_Z_abs.
Instance Op_Z_sgn : UnOp Z.sgn :=
{ TUOp := Z.sgn ; TUOpInj := ltac:(refl) }.
-Add UnOp Op_Z_sgn.
+Add Zify UnOp Op_Z_sgn.
Instance Op_Z_pow : BinOp Z.pow :=
{ TBOp := Z.pow ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_pow.
+Add Zify BinOp Op_Z_pow.
Instance Op_Z_pow_pos : BinOp Z.pow_pos :=
{ TBOp := Z.pow ; TBOpInj := ltac:(refl) }.
-Add BinOp Op_Z_pow_pos.
+Add Zify BinOp Op_Z_pow_pos.
Instance Op_Z_double : UnOp Z.double :=
{ TUOp := Z.mul 2 ; TUOpInj := Z.double_spec }.
-Add UnOp Op_Z_double.
+Add Zify UnOp Op_Z_double.
Instance Op_Z_pred_double : UnOp Z.pred_double :=
{ TUOp := fun x => 2 * x - 1 ; TUOpInj := Z.pred_double_spec }.
-Add UnOp Op_Z_pred_double.
+Add Zify UnOp Op_Z_pred_double.
Instance Op_Z_succ_double : UnOp Z.succ_double :=
{ TUOp := fun x => 2 * x + 1 ; TUOpInj := Z.succ_double_spec }.
-Add UnOp Op_Z_succ_double.
+Add Zify UnOp Op_Z_succ_double.
Instance Op_Z_square : UnOp Z.square :=
{ TUOp := fun x => x * x ; TUOpInj := Z.square_spec }.
-Add UnOp Op_Z_square.
+Add Zify UnOp Op_Z_square.
Instance Op_Z_div2 : UnOp Z.div2 :=
{ TUOp := fun x => x / 2 ; TUOpInj := Z.div2_div }.
-Add UnOp Op_Z_div2.
+Add Zify UnOp Op_Z_div2.
Instance Op_Z_quot2 : UnOp Z.quot2 :=
{ TUOp := fun x => Z.quot x 2 ; TUOpInj := Zeven.Zquot2_quot }.
-Add UnOp Op_Z_quot2.
+Add Zify UnOp Op_Z_quot2.
Lemma of_nat_to_nat_eq : forall x, Z.of_nat (Z.to_nat x) = Z.max 0 x.
Proof.
@@ -455,49 +455,28 @@ Qed.
Instance Op_Z_to_nat : UnOp Z.to_nat :=
{ TUOp := fun x => Z.max 0 x ; TUOpInj := of_nat_to_nat_eq }.
-Add UnOp Op_Z_to_nat.
+Add Zify UnOp Op_Z_to_nat.
(** Specification of derived operators over Z *)
-Lemma z_max_spec : forall n m,
- n <= Z.max n m /\ m <= Z.max n m /\ (Z.max n m = n \/ Z.max n m = m).
-Proof.
- intros.
- generalize (Z.le_max_l n m).
- generalize (Z.le_max_r n m).
- generalize (Z.max_spec_le n m).
- intuition idtac.
-Qed.
-
Instance ZmaxSpec : BinOpSpec Z.max :=
{| BPred := fun n m r => n < m /\ r = m \/ m <= n /\ r = n ; BSpec := Z.max_spec|}.
-Add Spec ZmaxSpec.
-
-Lemma z_min_spec : forall n m,
- Z.min n m <= n /\ Z.min n m <= m /\ (Z.min n m = n \/ Z.min n m = m).
-Proof.
- intros.
- generalize (Z.le_min_l n m).
- generalize (Z.le_min_r n m).
- generalize (Z.min_spec_le n m).
- intuition idtac.
-Qed.
-
+Add Zify BinOpSpec ZmaxSpec.
Instance ZminSpec : BinOpSpec Z.min :=
{| BPred := fun n m r => n < m /\ r = n \/ m <= n /\ r = m ;
BSpec := Z.min_spec |}.
-Add Spec ZminSpec.
+Add Zify BinOpSpec ZminSpec.
Instance ZsgnSpec : UnOpSpec Z.sgn :=
{| UPred := fun n r : Z => 0 < n /\ r = 1 \/ 0 = n /\ r = 0 \/ n < 0 /\ r = - (1) ;
USpec := Z.sgn_spec|}.
-Add Spec ZsgnSpec.
+Add Zify UnOpSpec ZsgnSpec.
Instance ZabsSpec : UnOpSpec Z.abs :=
{| UPred := fun n r: Z => 0 <= n /\ r = n \/ n < 0 /\ r = - n ;
USpec := Z.abs_spec|}.
-Add Spec ZabsSpec.
+Add Zify UnOpSpec ZabsSpec.
(** Saturate positivity constraints *)
@@ -508,7 +487,7 @@ Instance SatProd : Saturate Z.mul :=
PRes := fun r => 0 <= r;
SatOk := Z.mul_nonneg_nonneg
|}.
-Add Saturate SatProd.
+Add Zify Saturate SatProd.
Instance SatProdPos : Saturate Z.mul :=
{|
@@ -517,7 +496,7 @@ Instance SatProdPos : Saturate Z.mul :=
PRes := fun r => 0 < r;
SatOk := Z.mul_pos_pos
|}.
-Add Saturate SatProdPos.
+Add Zify Saturate SatProdPos.
Lemma pow_pos_strict :
forall a b,
@@ -536,4 +515,4 @@ Instance SatPowPos : Saturate Z.pow :=
PRes := fun r => 0 < r;
SatOk := pow_pos_strict
|}.
-Add Saturate SatPowPos.
+Add Zify Saturate SatPowPos.