(**************************************************************************) (* *) (* SMTCoq *) (* Copyright (C) 2011 - 2022 *) (* *) (* See file "AUTHORS" for the list of authors *) (* *) (* This file is distributed under the terms of the CeCILL-C licence *) (* *) (**************************************************************************) Require Import Bool List Int63 PArray Psatz ZArith. Require Import Misc State SMT_terms FArray SMT_classes. Import Form. Import Atom. Local Open Scope array_scope. Local Open Scope int63_scope. Section certif. Variable t_form : PArray.array Form.form. Variable t_atom : PArray.array Atom.atom. Local Notation get_atom := (PArray.get t_atom) (only parsing). Local Notation get_form := (PArray.get t_form) (only parsing). Definition check_roweq lres := if Lit.is_pos lres then match get_form (Lit.blit lres) with | Fatom a => match get_atom a with | Abop (BO_eq te) xa v => match get_atom xa with | Abop (BO_select ti1 te1) sa i => match get_atom sa with | Atop (TO_store ti2 te2) fa j v2 => if Typ.eqb ti1 ti2 && Typ.eqb te te1 && Typ.eqb te te2 && (i =? j) && (v =? v2) then lres::nil else C._true | _ => C._true end | _ => C._true end | _ => C._true end | _ => C._true end else C._true. Definition store_of_me a b := match get_atom b with | Atop (TO_store ti te) a' i _ => if (a' =? a) then Some (ti, te, i) else None | _ => None end. Definition check_rowneq cl := match cl with | leqij :: leqrow :: nil => if Lit.is_pos leqij && Lit.is_pos leqrow then match get_form (Lit.blit leqij), get_form (Lit.blit leqrow) with | Fatom eqij, Fatom eqrow => match get_atom eqij, get_atom eqrow with | Abop (BO_eq ti) i j, Abop (BO_eq te) xa x => match get_atom xa, get_atom x with | Abop (BO_select ti1 te1) sa j1, Abop (BO_select ti2 te2) sa2 j2 => if Typ.eqb ti ti1 && Typ.eqb ti ti2 && Typ.eqb te te1 && Typ.eqb te te2 then match store_of_me sa sa2, store_of_me sa2 sa with | Some (ti3, te3, i1), None | None, Some (ti3, te3, i1) => if Typ.eqb ti ti3 && Typ.eqb te te3 && (((i1 =? i) && (j1 =? j) && (j2 =? j)) || ((i1 =? j) && (j1 =? i) && (j2 =? i))) then cl else C._true | _, _ => C._true end else C._true | _, _ => C._true end | _, _ => C._true end | _, _ => C._true end else C._true | _ => C._true end. Definition eq_sel_sym ti te a b sela selb := match get_atom sela, get_atom selb with | Abop (BO_select ti1 te1) a' d1, Abop (BO_select ti2 te2) b' d2 => Typ.eqb ti ti1 && Typ.eqb ti ti2 && Typ.eqb te te1 && Typ.eqb te te2 && (a =? a') && (b =? b') && (d1 =? d2) && match get_atom d1 with | Abop (BO_diffarray ti3 te3) a3 b3 => Typ.eqb ti ti3 && Typ.eqb te te3 && (a3 =? a) && (b3 =? b) | _ => false end | _, _ => false end. Definition check_ext lres := if Lit.is_pos lres then match get_form (Lit.blit lres) with | For args => if PArray.length args =? 2 then let l1 := args.[0] in let l2 := args.[1] in if Lit.is_pos l1 && negb (Lit.is_pos l2) then match get_form (Lit.blit l1), get_form (Lit.blit l2) with | Fatom eqa, Fatom eqsel => match get_atom eqa, get_atom eqsel with | Abop (BO_eq (Typ.TFArray ti te)) a b, Abop (BO_eq te') sela selb => if Typ.eqb te te' && (eq_sel_sym ti te a b sela selb || eq_sel_sym ti te b a sela selb) then lres :: nil else C._true | _, _ => C._true end | _, _ => C._true end else C._true else C._true | _ => C._true end else C._true. Section Correct. Variables (t_i : array typ_compdec) (t_func : array (Atom.tval t_i)) (ch_atom : Atom.check_atom t_atom) (ch_form : Form.check_form t_form) (wt_t_atom : Atom.wt t_i t_func t_atom). Local Notation check_atom := (check_aux t_i t_func (get_type t_i t_func t_atom)). Local Notation interp_form_hatom := (Atom.interp_form_hatom t_i t_func t_atom). Local Notation interp_form_hatom_bv := (Atom.interp_form_hatom_bv t_i t_func t_atom). Local Notation rho := (Form.interp_state_var interp_form_hatom interp_form_hatom_bv t_form). Local Notation t_interp := (t_interp t_i t_func t_atom). Local Notation interp_atom := (interp_aux t_i t_func (get t_interp)). Let wf_t_atom : Atom.wf t_atom. Proof. destruct (Atom.check_atom_correct _ ch_atom); auto. Qed. Let def_t_atom : default t_atom = Atom.Acop Atom.CO_xH. Proof. destruct (Atom.check_atom_correct _ ch_atom); auto. Qed. Let def_t_form : default t_form = Form.Ftrue. Proof. destruct (Form.check_form_correct interp_form_hatom interp_form_hatom_bv _ ch_form) as [H _]; destruct H; auto. Qed. Let wf_t_form : Form.wf t_form. Proof. destruct (Form.check_form_correct interp_form_hatom interp_form_hatom_bv _ ch_form) as [H _]; destruct H; auto. Qed. Let wf_rho : Valuation.wf rho. Proof. destruct (Form.check_form_correct interp_form_hatom interp_form_hatom_bv _ ch_form); auto. Qed. Let rho_interp : forall x : int, rho x = Form.interp interp_form_hatom interp_form_hatom_bv t_form (t_form.[ x]). Proof. intros x;apply wf_interp_form;trivial. Qed. Definition wf := aforallbi lt_form t_form. Hypothesis wf_t_i : wf. Notation atom := int (only parsing). Lemma valid_check_roweq lres : C.valid rho (check_roweq lres). Proof. unfold check_roweq. case_eq (Lit.is_pos lres); intro Heq; simpl; try now apply C.interp_true. case_eq (t_form .[ Lit.blit lres]); try (intros; now apply C.interp_true). intros a Heq2. case_eq (t_atom .[ a]); try (intros; now apply C.interp_true). intros [ | | | | | | | |N|N|N|N|N|N|N|N| | | | ] a1 a2 Heq3; try (intros; now apply C.interp_true). case_eq (t_atom .[ a1]); try (intros; now apply C.interp_true). intros [ | | | | | | | |N|N|N|N|N|N|N|N| | | | ] b1 b2 Heq4; try (intros; now apply C.interp_true). case_eq (t_atom .[ b1]); try (intros; now apply C.interp_true). intros [ ] c1 c2 c3 Heq5. (* roweq *) - case_eq (Typ.eqb t0 t2 && Typ.eqb t t1 && Typ.eqb t t3 && (b2 =? c2) && (a2 =? c3)); simpl; intros Heq6; try (now apply C.interp_true). unfold C.valid. simpl. rewrite orb_false_r. unfold Lit.interp. rewrite Heq. unfold Var.interp. rewrite wf_interp_form; trivial. rewrite Heq2. simpl. rewrite !andb_true_iff in Heq6. destruct Heq6 as ((((Heq6a, Heq6b), Heq6c), Heq6d), Heq6e). apply Typ.eqb_spec in Heq6a. apply Typ.eqb_spec in Heq6b. apply Typ.eqb_spec in Heq6c. apply Int63.eqb_spec in Heq6d. apply Int63.eqb_spec in Heq6e. pose proof (rho_interp (Lit.blit lres)) as Hrho. rewrite Heq2 in Hrho. simpl in Hrho. generalize wt_t_atom. unfold Atom.wt. unfold is_true. rewrite aforallbi_spec;intros. pose proof (H a). assert (a CompDec ty) (Typ.interp_compdec_aux t_i v_typed2')) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2'))) (@eqbtype_of_compdec (@type_compdec (@projT1 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2')) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2'))) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2')))) (@ord_of_compdec (@type_compdec (@projT1 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2')) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2'))) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2'))) (@comp_of_compdec (@type_compdec (@projT1 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2')) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2'))) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2'))) (@EqbToDecType (@type_compdec (@projT1 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1')) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1'))) (@eqbtype_of_compdec (@type_compdec (@projT1 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1')) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1'))) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1')))) (@ord_of_compdec (@type_compdec (@projT1 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1')) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1'))) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1'))) (@comp_of_compdec (@type_compdec (@projT1 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1')) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1'))) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1'))) (@inh_of_compdec (@type_compdec (@projT1 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2')) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2'))) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typed2'))) (@inh_of_compdec (@type_compdec (@projT1 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1')) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1'))) (@projT2 Type (fun ty : Type => CompDec ty) (Typ.interp_compdec_aux t_i v_typec1'))) v_valf1 v_valf2)). intros H5. specialize (H5 Htid2'''). rewrite <- H5. specialize (Atom.Bval_inj2 t_i v_typed2' (v_vale2) (v_vald2)). intros. unfold Atom.interp_form_hatom, interp_hatom in H. rewrite !Atom.t_interp_wf in H; trivial. rewrite Heq7 in H. simpl in H. rewrite !Atom.t_interp_wf in H; trivial. rewrite Htib1, Htib2 in H. simpl in H. rewrite !Typ.cast_refl in H. simpl in H. apply Typ.i_eqb_spec_false in H. destruct Heq1314 as [Heq1314 | Heq1314]; destruct Heq1314 as (((Heq13a, Heq13b), Heq13c), (Heq13d, Heq13e)); subst. - rewrite Htie2 in Htid2. rewrite Htid1 in Htib1. rewrite Htie1 in Htib2. rewrite Htid1 in Htif1. rewrite Htie1 in Htif2. rewrite (Atom.Bval_inj2 t_i _ _ _ Htib1) in *. rewrite (Atom.Bval_inj2 t_i _ _ _ Htib2) in *. rewrite (Atom.Bval_inj2 t_i _ _ _ Htif1) in *. rewrite (Atom.Bval_inj2 t_i _ _ _ Htif2) in *. rewrite (Atom.Bval_inj2 t_i _ _ _ Htid2) in *. now apply select_at_diff. - rewrite Htie2 in Htid2. rewrite Htid1 in Htib2. rewrite Htie1 in Htib1. rewrite Htid1 in Htif1. rewrite Htie1 in Htif2. rewrite (Atom.Bval_inj2 t_i _ _ _ Htib1) in *. rewrite (Atom.Bval_inj2 t_i _ _ _ Htib2) in *. rewrite (Atom.Bval_inj2 t_i _ _ _ Htif1) in *. rewrite (Atom.Bval_inj2 t_i _ _ _ Htif2) in *. rewrite (Atom.Bval_inj2 t_i _ _ _ Htid2) in *. apply select_at_diff. red in H. red. intro. apply H. auto. Qed. End Correct. End certif.