aboutsummaryrefslogtreecommitdiffstats
path: root/src/State.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/State.v')
-rw-r--r--src/State.v572
1 files changed, 572 insertions, 0 deletions
diff --git a/src/State.v b/src/State.v
new file mode 100644
index 0000000..d793410
--- /dev/null
+++ b/src/State.v
@@ -0,0 +1,572 @@
+(**************************************************************************)
+(* *)
+(* SMTCoq *)
+(* Copyright (C) 2011 - 2015 *)
+(* *)
+(* Michaël Armand *)
+(* Benjamin Grégoire *)
+(* Chantal Keller *)
+(* *)
+(* Inria - École Polytechnique - MSR-Inria Joint Lab *)
+(* *)
+(* This file is distributed under the terms of the CeCILL-C licence *)
+(* *)
+(**************************************************************************)
+
+Require Import List.
+Require Import Bool.
+Require Import Int63.
+Require Import PArray.
+
+(* Require Import AxiomesInt. *)
+
+Local Open Scope int63_scope.
+Local Open Scope array_scope.
+
+Coercion is_true (x: bool) := x = true.
+
+Set Vm Optimize.
+
+Notation var := int (only parsing).
+
+(* Variables interpretation *)
+Module Valuation.
+(* TODO : Should be var -> Prop *)
+ Definition t := var -> bool.
+ Definition wf (rho : t) : Prop := rho 0 /\ ~ rho 1.
+
+End Valuation.
+
+
+Module Var.
+
+ Definition _true : var := 0. (* true *)
+ Register _true as PrimInline.
+
+ Definition _false : var := 1. (* false *)
+
+ Definition interp (rho:Valuation.t) (x:var) : bool := rho x.
+
+ Lemma interp_true : forall rho, Valuation.wf rho -> interp rho _true.
+ Proof. intros rho [H _];exact H. Qed.
+
+ Lemma interp_false : forall rho, Valuation.wf rho -> ~ interp rho _false.
+ Proof. intros rho [_ H];exact H. Qed.
+
+End Var.
+
+Notation _lit := int (only parsing).
+
+Module Lit.
+
+ Definition is_pos (l:_lit) := is_even l.
+ Register is_pos as PrimInline.
+
+ Definition blit (l:_lit) : var := l >> 1.
+ Register blit as PrimInline.
+
+ Definition lit (x:var) : _lit := x << 1.
+ Register lit as PrimInline.
+
+ Definition neg (l:_lit) : _lit := l lxor 1.
+ Register neg as PrimInline.
+
+ Definition nlit (x:var) : _lit := neg (lit x).
+ Register nlit as PrimInline.
+
+ Definition _true : _lit := Eval compute in lit Var._true.
+ Register _true as PrimInline.
+
+ Lemma lit_true : _true = lit Var._true.
+ Proof. reflexivity. Qed.
+
+ Definition _false : _lit := Eval compute in lit Var._false.
+ Register _false as PrimInline.
+
+ Lemma lit_false : _false = lit Var._false.
+ Proof. reflexivity. Qed.
+
+ Definition eqb (l l' : _lit) := l == l'.
+ Register eqb as PrimInline.
+
+ Lemma eqb_spec : forall l l', eqb l l' = true <-> l = l'.
+ Proof eqb_spec.
+
+ Lemma neg_involutive : forall l, neg (neg l) = l.
+ Proof.
+ unfold neg;intros; rewrite <- lxor_assoc;change (1 lxor 1) with 0;rewrite lxor_0_r;trivial.
+ Qed.
+
+ Lemma blit_neg : forall l, blit (neg l) = blit l.
+ Proof.
+ unfold blit, neg;intros l.
+ rewrite lxor_lsr, lxor_0_r;trivial.
+ Qed.
+
+ Lemma lit_blit: forall l,
+ is_pos l = true -> lit (blit l) = l.
+ Proof.
+ unfold is_pos, lit, blit;intros.
+ rewrite (bit_xor_split l) at 2.
+ rewrite is_even_bit, negb_true_iff in H;rewrite H.
+ symmetry;apply lxor_0_r.
+ Qed.
+
+ Lemma lit_blit_neg: forall l,
+ is_pos l = false -> lit (blit l) = neg l.
+ Proof.
+ unfold is_pos, lit, blit;intros.
+ rewrite (bit_xor_split l) at 2.
+ rewrite is_even_bit, negb_false_iff in H;rewrite H.
+ rewrite <- (neg_involutive ((l >> 1) << 1)) at 1;trivial.
+ Qed.
+
+ Lemma nlit_blit: forall l,
+ is_pos l = false -> nlit (blit l) = l.
+ Proof.
+ unfold nlit;intros;rewrite lit_blit_neg;auto using neg_involutive.
+ Qed.
+
+ Lemma nlit_blit_neg: forall l,
+ is_pos l = true -> nlit (blit l) = neg l.
+ Proof.
+ unfold nlit;intros;rewrite lit_blit;auto using neg_involutive.
+ Qed.
+
+ Lemma is_pos_lit : forall l,
+ is_pos (lit l) = true.
+ Proof.
+ unfold is_pos, lit;apply is_even_lsl_1.
+ Qed.
+
+ Lemma is_pos_neg : forall l,
+ is_pos (neg l) = negb (is_pos l).
+ Proof.
+ unfold neg, is_pos;intros l.
+ rewrite is_even_xor, xorb_false_r;trivial.
+ Qed.
+
+ Lemma is_pos_nlit : forall l,
+ is_pos (nlit l) = false.
+ Proof.
+ unfold nlit;intros l;rewrite is_pos_neg, is_pos_lit;trivial.
+ Qed.
+
+ Lemma is_pos_true : is_pos _true.
+ Proof. reflexivity. Qed.
+
+ Lemma is_pos_false : is_pos _false.
+ Proof. reflexivity. Qed.
+
+ Lemma blit_pos :forall a b,
+ Lit.blit a = Lit.blit b -> Lit.is_pos a = Lit.is_pos b ->
+ a = b.
+ Proof lsr_is_even_eq.
+
+ Lemma blit_lit : forall l, blit (lit (blit l)) = blit l.
+ Proof.
+ intros l;case_eq (is_pos l);intros.
+ rewrite lit_blit;trivial.
+ rewrite lit_blit_neg, blit_neg;trivial.
+ Qed.
+
+ Lemma blit_nlit : forall l, blit (nlit (blit l)) = blit l.
+ Proof.
+ intros l;case_eq (is_pos l);intros.
+ rewrite nlit_blit_neg, blit_neg;trivial.
+ rewrite nlit_blit;trivial.
+ Qed.
+
+ Lemma blit_true : blit _true = Var._true.
+ Proof. reflexivity. Qed.
+
+ Lemma blit_false : blit _false = Var._false.
+ Proof. reflexivity. Qed.
+
+ (* Interpretation of a literal *)
+ Definition interp rho (l:_lit) :=
+ if is_pos l then Var.interp rho (blit l)
+ else negb (Var.interp rho (blit l)).
+
+ Lemma interp_true : forall rho, Valuation.wf rho -> interp rho _true.
+ Proof.
+ intros rho Hwf;unfold interp;rewrite is_pos_true, blit_true.
+ apply Var.interp_true;trivial.
+ Qed.
+
+ Lemma interp_false : forall rho, Valuation.wf rho -> ~interp rho _false.
+ Proof.
+ intros rho Hwf;unfold interp;rewrite is_pos_false, blit_false.
+ apply Var.interp_false;trivial.
+ Qed.
+
+ Lemma interp_neg : forall rho l, interp rho (neg l) = negb (interp rho l).
+ Proof.
+ intros rho l;unfold interp;rewrite is_pos_neg, blit_neg.
+ destruct (is_pos l);simpl;auto using negb_involutive.
+ Qed.
+
+ Lemma interp_lit : forall rho l, interp rho (lit (blit l)) = Var.interp rho (blit l).
+ Proof.
+ intros;unfold interp;rewrite is_pos_lit, blit_lit;trivial.
+ Qed.
+
+ Lemma interp_nlit : forall rho l, interp rho (nlit (blit l)) = negb (Var.interp rho (blit l)).
+ Proof.
+ unfold nlit;intros rho l;rewrite interp_neg, interp_lit;trivial.
+ Qed.
+
+ Lemma interp_eq_compat : forall rho1 rho2 l,
+ rho1 (blit l) = rho2 (blit l) ->
+ interp rho1 l = interp rho2 l.
+ Proof.
+ unfold interp, Var.interp;intros rho1 rho2 l Heq;rewrite Heq;trivial.
+ Qed.
+
+ Lemma lxor_neg : forall l1 l2, (l1 lxor l2 == 1) = true -> l1 = Lit.neg l2.
+ Proof.
+ unfold Lit.neg; intros l1 l2;rewrite eqb_spec;intros Heq;rewrite <- Heq.
+ rewrite lxor_comm, <- lxor_assoc, lxor_nilpotent, lxor_0_r;trivial.
+ Qed.
+
+End Lit.
+
+
+Lemma compare_spec' : forall x y,
+ match x ?= y with
+ | Lt => x < y
+ | Eq => x = y
+ | Gt => y < x
+ end.
+Proof.
+ intros x y;rewrite compare_def_spec;unfold compare_def.
+ case_eq (x < y);intros;[reflexivity | ].
+ case_eq (x == y);intros.
+ rewrite <- eqb_spec;trivial.
+ rewrite <- not_true_iff_false in H, H0.
+ unfold is_true in *;rewrite ltb_spec in H |- *;rewrite eqb_spec in H0.
+ assert ([|x|] <> [|y|]) by (intros Heq;apply H0, to_Z_inj;trivial);omega.
+Qed.
+
+
+Module C.
+
+ Definition t := list _lit.
+
+ Definition interp (rho:Valuation.t) (l:t) :=
+ List.existsb (Lit.interp rho) l.
+
+ Definition valid rho c :=
+ interp rho c = true.
+
+ Definition _true : t := Lit._true :: nil.
+
+ Definition is_false (c:t) :=
+ match c with
+ | nil => true
+ | _ => false
+ end.
+
+ Section OR.
+
+ Variable or : t -> t -> t.
+ Variable l1 : _lit.
+ Variable c1 : t.
+
+ Fixpoint or_aux (c2:t) :=
+ match c2 with
+ | nil => l1 :: c1
+ | l2::c2' =>
+ match l1 ?= l2 with
+ | Eq => l1 :: or c1 c2'
+ | Lt => l1 :: or c1 c2
+ | Gt => l2 :: or_aux c2'
+ end
+ end.
+
+ Variable rho : Valuation.t.
+ Hypothesis or_correct : forall c2,
+ interp rho (or c1 c2) = interp rho c1 || interp rho c2.
+
+ Lemma or_aux_correct : forall c2,
+ interp rho (or_aux c2) = interp rho (l1::c1) || interp rho c2.
+ Proof.
+ induction c2;simpl.
+ rewrite orb_false_r;trivial.
+ generalize (compare_spec' l1 a);destruct (l1 ?= a);intros H;simpl.
+ rewrite H;destruct (Lit.interp rho a);trivial.
+ rewrite !orb_false_l, or_correct;trivial.
+ rewrite or_correct;simpl;rewrite orb_assoc;trivial.
+ rewrite IHc2;simpl.
+ destruct (Lit.interp rho a);simpl;trivial.
+ rewrite orb_true_r;trivial.
+ Qed.
+
+ End OR.
+
+ Fixpoint or (c1 c2:t) {struct c1} : t :=
+ match c1, c2 with
+ | nil, _ => c2
+ | _, nil => c1
+ | l1::c1, l2::c2' =>
+ match compare l1 l2 with
+ | Eq => l1 :: or c1 c2'
+ | Lt => l1 :: or c1 c2
+ | Gt => l2 :: or_aux or l1 c1 c2'
+ end
+ end.
+
+ Lemma or_correct : forall rho c1 c2,
+ interp rho (or c1 c2) = interp rho c1 || interp rho c2.
+ Proof.
+ induction c1;simpl;trivial.
+ destruct c2;simpl.
+ rewrite orb_false_r;trivial.
+ generalize (compare_spec' a i);destruct (a ?= i);intros H;simpl.
+ rewrite H, IHc1;simpl;destruct (Lit.interp rho i);simpl;trivial.
+ rewrite IHc1, orb_assoc;trivial.
+ rewrite or_aux_correct;simpl;trivial.
+ destruct (Lit.interp rho i);trivial.
+ simpl;rewrite !orb_true_r;trivial.
+ Qed.
+
+ Section RESOLVE.
+
+ Variable resolve : t -> t -> t.
+ Variable l1 : _lit.
+ Variable c1 : t.
+
+ Fixpoint resolve_aux (c2:t) : t :=
+ match c2 with
+ | nil => _true
+ | l2::c2' =>
+ match compare l1 l2 with
+ | Eq => l1 :: resolve c1 c2'
+ | Lt => if l1 lxor l2 == 1 then or c1 c2' else l1 :: resolve c1 c2
+ | Gt =>
+ if l1 lxor l2 == 1 then or c1 c2' else l2 :: resolve_aux c2'
+ end
+ end.
+
+ Lemma resolve_aux_correct : forall rho,
+ (forall c2, interp rho c1 -> interp rho c2 -> interp rho (resolve c1 c2)) ->
+ interp rho (l1 :: c1) ->
+ forall c2, interp rho c2 ->
+ interp rho (resolve_aux c2).
+ Proof.
+ intros rho resolve_correct Hc1;simpl in Hc1.
+ induction c2;simpl;try discriminate.
+ generalize (compare_spec' l1 a);destruct (l1 ?= a);intros;subst;simpl.
+ simpl in Hc1;destruct (Lit.interp rho a);simpl in *;auto.
+ generalize (Lit.lxor_neg l1 a);destruct (l1 lxor a == 1);intros.
+ rewrite or_correct.
+ rewrite H1, Lit.interp_neg in Hc1;trivial;destruct (Lit.interp rho a).
+ simpl in Hc1;rewrite Hc1;trivial.
+ simpl in H0;rewrite H0, orb_true_r;trivial.
+ simpl;destruct (Lit.interp rho l1);simpl;auto.
+ generalize (Lit.lxor_neg l1 a);destruct (l1 lxor a == 1);intros.
+ rewrite or_correct.
+ rewrite H1, Lit.interp_neg in Hc1;trivial;destruct (Lit.interp rho a).
+ simpl in Hc1;rewrite Hc1;trivial.
+ simpl in H0;rewrite H0, orb_true_r;trivial.
+ simpl;destruct (Lit.interp rho a);simpl;auto.
+ Qed.
+
+ End RESOLVE.
+
+ Fixpoint resolve (c1 c2:t) {struct c1} : t :=
+ match c1, c2 with
+ | nil, _ => _true
+ | _, nil => _true
+ | l1::c1, l2::c2' =>
+ match compare l1 l2 with
+ | Eq => l1 :: resolve c1 c2'
+ | Lt => if l1 lxor l2 == 1 then or c1 c2' else l1 :: resolve c1 c2
+ | Gt =>
+ if l1 lxor l2 == 1 then or c1 c2' else l2 :: resolve_aux resolve l1 c1 c2'
+ end
+ end.
+
+ Lemma resolve_correct : forall rho c1 c2,
+ interp rho c1 -> interp rho c2 ->
+ interp rho (resolve c1 c2).
+ Proof.
+ induction c1;simpl;try discriminate.
+ destruct c2;simpl;try discriminate.
+ intros Hc1 Hc2.
+ generalize (compare_spec' a i);destruct (a ?= i);intros;subst;simpl.
+ destruct (Lit.interp rho i);simpl in *;auto.
+ generalize (Lit.lxor_neg a i);destruct (a lxor i == 1);intros.
+ rewrite or_correct.
+ rewrite H0, Lit.interp_neg in Hc1;trivial;destruct (Lit.interp rho i).
+ simpl in Hc1;rewrite Hc1;trivial.
+ simpl in Hc2;rewrite Hc2, orb_true_r;trivial.
+ simpl;destruct (Lit.interp rho a);simpl;auto.
+ generalize (Lit.lxor_neg a i);destruct (a lxor i == 1);intros.
+ rewrite or_correct.
+ rewrite H0, Lit.interp_neg in Hc1;trivial;destruct (Lit.interp rho i).
+ simpl in Hc1;rewrite Hc1;trivial.
+ simpl in Hc2;rewrite Hc2, orb_true_r;trivial.
+ simpl;destruct (Lit.interp rho i);simpl;auto using resolve_aux_correct.
+ Qed.
+
+ Lemma interp_true : forall rho, Valuation.wf rho -> interp rho _true = true.
+ Proof.
+ unfold _true, interp;intros rho Hwf;simpl.
+ rewrite Lit.interp_true;trivial.
+ Qed.
+
+ Lemma is_false_correct :
+ forall c, is_false c = true ->
+ forall rho, ~valid rho c.
+ Proof.
+ unfold valid, interp;destruct c;simpl; auto;discriminate.
+ Qed.
+
+End C.
+
+
+Notation clause_id := int (only parsing).
+
+Notation resolution := (array clause_id) (only parsing).
+
+Module S.
+
+ Definition t := array C.t.
+
+ Definition get (s:t) (cid:clause_id) := s.[cid].
+ Register get as PrimInline.
+
+ (* Do not use this function outside this module *)
+ (* expect if you are sure that [c = sort_uniq c] *)
+ Definition internal_set (s:t) (cid:clause_id) (c:C.t) : t := s.[cid <- c].
+ Register internal_set as PrimInline.
+
+ Definition make (nclauses : int) : t :=
+ PArray.make nclauses C._true.
+
+ Definition valid rho s :=
+ forall id, C.valid rho (get s id).
+
+
+ (* Specification of make *)
+
+ Lemma valid_make : forall rho nclauses,
+ Valuation.wf rho ->
+ valid rho (make nclauses).
+ Proof.
+ unfold valid, make, get;intros.
+ rewrite PArray.get_make; apply C.interp_true;trivial.
+ Qed.
+
+
+ (* Specification of get *)
+
+ Lemma valid_get : forall rho s, valid rho s ->
+ forall id, C.valid rho (get s id).
+ Proof. auto. Qed.
+
+
+ (* Specification of internal_set *)
+
+ Lemma valid_internal_set :
+ forall rho s, valid rho s ->
+ forall c, C.valid rho c ->
+ forall id, valid rho (set s id c).
+ Proof.
+ unfold valid, get, set;simpl;intros.
+ destruct (Int63Properties.reflect_eqb id id0);subst.
+ case_eq (id0 < length s);intros.
+ rewrite PArray.get_set_same;trivial.
+ rewrite PArray.get_outofbound.
+ rewrite PArray.default_set.
+ rewrite <- (PArray.get_outofbound _ _ (length s)); trivial.
+ rewrite <- not_true_iff_false, ltb_spec;auto with zarith.
+ rewrite PArray.length_set;trivial.
+ rewrite get_set_other;trivial.
+ Qed.
+
+ (* Building clause *)
+ (* Same as set but without precondition *)
+
+ (* TODO: It can be a good idea to change the insertion sort algorithm *)
+
+ Fixpoint insert l1 c :=
+ match c with
+ | nil => l1:: nil
+ | l2 :: c' =>
+ match l1 ?= l2 with
+ | Lt => if l1 lxor l2 == 1 then C._true else l1 :: c
+ | Eq => c
+ | Gt => if l1 lxor l2 == 1 then C._true else l2 :: insert l1 c'
+ end
+ end.
+
+ Fixpoint sort_uniq c :=
+ match c with
+ | nil => nil
+ | l1 :: c => insert l1 (sort_uniq c)
+ end.
+
+ Lemma insert_correct : forall rho (Hwf:Valuation.wf rho) l1 c,
+ C.interp rho (insert l1 c) = C.interp rho (l1 :: c).
+ Proof.
+ intros rho Hwf l1;induction c;simpl;trivial.
+ generalize (compare_spec' l1 a);destruct (l1 ?= a);intros;subst;simpl.
+ destruct (Lit.interp rho a);simpl in *;auto.
+ generalize (Lit.lxor_neg l1 a);destruct (l1 lxor a == 1);intros;trivial.
+ rewrite C.interp_true;trivial.
+ rewrite H0, Lit.interp_neg;trivial;destruct (Lit.interp rho a);trivial.
+ generalize (Lit.lxor_neg l1 a);destruct (l1 lxor a == 1);intros.
+ rewrite C.interp_true;trivial.
+ rewrite H0, Lit.interp_neg;trivial;destruct (Lit.interp rho a);trivial.
+ simpl;rewrite orb_assoc,(orb_comm (Lit.interp rho l1)),<-orb_assoc,IHc;trivial.
+ Qed.
+
+ Lemma sort_uniq_correct : forall rho (Hwf:Valuation.wf rho) c,
+ C.interp rho (sort_uniq c) = C.interp rho c.
+ Proof.
+ intros rho Hwf;induction c;simpl;trivial.
+ rewrite insert_correct;trivial;simpl;rewrite IHc;trivial.
+ Qed.
+
+ Definition set_clause (s:t) pos (c:C.t) : t :=
+ set s pos (sort_uniq c).
+
+ Lemma valid_set_clause :
+ forall rho s, Valuation.wf rho -> valid rho s -> forall pos c,
+ C.valid rho c -> valid rho (set_clause s pos c).
+ Proof.
+ unfold valid, get, set_clause. intros rho s Hrho Hs pos c Hc id.
+ destruct (Int63Properties.reflect_eqb pos id);subst.
+ case_eq (id < length s); intro H.
+ unfold get;rewrite PArray.get_set_same; trivial.
+ unfold C.valid;rewrite sort_uniq_correct;trivial.
+ generalize (Hs id);rewrite !PArray.get_outofbound, PArray.default_set;trivial.
+ rewrite length_set;trivial.
+ rewrite get_set_other;trivial.
+ Qed.
+
+
+ (* Resolution *)
+
+ Definition set_resolve (s:t) pos (r:resolution) : t :=
+ let len := PArray.length r in
+ if len == 0 then s
+ else
+ let c := foldi (fun i c => C.resolve (get s (r.[i])) c) 1 (len - 1)
+ (get s (r.[0])) in
+ internal_set s pos c.
+
+ Lemma valid_set_resolve :
+ forall rho s, Valuation.wf rho -> valid rho s ->
+ forall pos r, valid rho (set_resolve s pos r).
+ Proof.
+ unfold set_resolve; intros rho s Hrho Hv pos r.
+ destruct (Int63Properties.reflect_eqb (length r) 0);[trivial | ].
+ apply valid_internal_set;trivial.
+ apply foldi_ind;auto.
+ intros i c _ _ Hc;apply C.resolve_correct;auto;apply Hv.
+ Qed.
+
+End S.