Library LSF_LWP_comparation
Require Import ZArith List EqNat Classical Max.
From mathcomp Require Import ssreflect ssrbool eqtype.
Require Import bipl seplog integral_type.
Require Import expr_b_dp.
Import seplog_Z_m.assert_m.
Import seplog_Z_m.assert_m.expr_m.
Import seplog_Z_m.
Local Open Scope heap_scope.
Local Open Scope seplog_expr_scope.
Local Open Scope seplog_cmd_scope.
Local Open Scope seplog_assert_scope.
Local Open Scope seplog_hoare_scope.
Local Close Scope Z_scope.
Require Import frag_list_triple.
Require Import frag_list_entail.
Import Fresh.
From mathcomp Require Import ssreflect ssrbool eqtype.
Require Import bipl seplog integral_type.
Require Import expr_b_dp.
Import seplog_Z_m.assert_m.
Import seplog_Z_m.assert_m.expr_m.
Import seplog_Z_m.
Local Open Scope heap_scope.
Local Open Scope seplog_expr_scope.
Local Open Scope seplog_cmd_scope.
Local Open Scope seplog_assert_scope.
Local Open Scope seplog_hoare_scope.
Local Close Scope Z_scope.
Require Import frag_list_triple.
Require Import frag_list_entail.
Import Fresh.
Smallfoot like proof-system (pure forward) with arithmetic
Inductive LSF : assrt -> @while.cmd cmd0 expr_b -> assrt -> Prop :=
| LSF_precond_stre : forall L1 L1' L2 c,
assrt_interp L1 ===> assrt_interp L1' ->
LSF L1' c L2 ->
LSF L1 c L2
| LSF_seq_assoc : forall P Q c1 c2 c3,
LSF P (c1; (c2; c3)) Q ->
LSF P ((c1; c2); c3) Q
| LSF_add_empty : forall P Q c,
LSF P (c; skip) Q ->
LSF P c Q
| LSF_empty: forall P Q,
assrt_interp P ===> assrt_interp Q ->
LSF P skip Q
| LSF_assign: forall pi sig Q c x e x',
fresh_assrt x' (pi, sig) ->
fresh_assrt x' Q ->
fresh_cmd x' c ->
fresh_e x' e ->
fresh_e x' (var_e x) ->
LSF (((subst_b pi (var_e x) (var_e x')) \&& (var_e x \= subst_e e (var_e x) (var_e x'))), subst_Sigma sig x (var_e x')) c Q ->
LSF (pi, sig) (x <- e ; c) Q
| LSF_lookup: forall pi sig e1 e2 e x Q c x',
(forall s, eval_b pi s -> eval_b (e1 \= e) s ) ->
fresh_assrt x' (pi, star sig (singl e1 e2)) ->
fresh_assrt x' Q ->
fresh_cmd x' c ->
fresh_e x' e ->
fresh_e x' (var_e x) ->
LSF (((subst_b pi (var_e x) (var_e x')) \&& ((var_e x) \= (subst_e e2 (var_e x) (var_e x')))), subst_Sigma (star sig (singl e1 e2)) x (var_e x')) c Q ->
LSF (pi,star sig (singl e1 e2)) (x <-* e; c) Q
| LSF_mutation: forall pi1 sig1 e1 e2 e3 e4 Q c,
(forall s, eval_b pi1 s -> eval_b (e1 \= e3) s ) ->
LSF (pi1,star sig1 (singl e1 e4)) c Q ->
LSF (pi1,star sig1 (singl e1 e2)) (e3 *<- e4 ; c) Q
| LSF_mutation': forall pi1 sig1 e1 e3 e4 Q c,
(forall s, eval_b pi1 s -> eval_b (e1 \= e3) s ) ->
LSF (pi1,star sig1 (singl e1 e4)) c Q ->
LSF (pi1,star sig1 (cell e1)) (e3 *<- e4 ; c) Q
| LSF_cond: forall b c1 c2 c Q pi sig,
LSF (pi \&& b, sig) (c1; c) Q ->
LSF (pi \&& (\~ b), sig) (c2 ; c) Q ->
LSF (pi, sig) ((If b Then c1 Else c2) ; c) Q
| LSF_unroll_lst_lookup: forall pi sig e1 e2 e x Q c x',
(forall s, eval_b pi s -> eval_b (e1 \= e) s ) ->
fresh_assrt x' (pi, star sig (lst e1 e2)) ->
fresh_assrt x' Q ->
fresh_cmd x' c ->
fresh_e x' e ->
fresh_e x' (var_e x) ->
(forall s, [ pi =b> (e1 \!= e2) ]b_s) ->
LSF ((pi \&& ((var_e x') \= e2) ,star sig (star (star (singl e1 (var_e x')) (cell (e1 \+ nat_e 1))) (lst (var_e x') e2)))) (x <-* e; c) Q ->
LSF ((pi \&& ((var_e x') \!= e2) ,star sig (star (star (singl e1 (var_e x')) (cell (e1 \+ nat_e 1))) (lst (var_e x') e2)))) (x <-* e; c) Q ->
LSF (pi,star sig (lst e1 e2)) (x <-* e; c) Q.
Axiom LSF_sound: forall P c Q,
LSF P c Q ->
{{assrt_interp P}} c {{assrt_interp Q}}.
Axiom LSF_lookup': forall pi sig e1 e2 e x Q c x',
(forall s, eval_b pi s -> eval_b (e1 \= e) s ) ->
x' = (max (var_max_cmd c) (max (var_max_assrt (pi,star sig (singl e1 e2))) (max (var_max_assrt Q) (max x (Max_ext.max_lst (vars e)))))) + 1 ->
LSF (((subst_b pi (var_e x) (var_e x')) \&& ((var_e x) \= (subst_e e2 (var_e x) (var_e x')))), subst_Sigma (star sig (singl e1 e2)) x (var_e x')) c Q ->
LSF (pi,star sig (singl e1 e2)) (x <-* e; c) Q.
Axiom LSF_assign': forall pi sig Q c x e x',
x' = (max (var_max_cmd c) (max (var_max_assrt (pi,sig)) (max (var_max_assrt Q) (max x (Max_ext.max_lst (vars e)))))) + 1 ->
LSF (((subst_b pi (var_e x) (var_e x')) \&& ((var_e x) \= (subst_e e (var_e x) (var_e x')))), subst_Sigma sig x (var_e x')) c Q ->
LSF (pi, sig) (x <- e ; c) Q.
Axiom LSF_unroll_lst_lookup': forall pi sig e1 e2 e x Q c x',
(forall s, eval_b pi s -> eval_b (e1 \= e) s ) ->
x' = (max (var_max_cmd c) (max (var_max_assrt (pi,star sig (lst e1 e2))) (max (var_max_assrt Q) (max x (Max_ext.max_lst (vars e)))))) + 1 ->
(forall s, [ pi =b> (e1 \!= e2) ]b_s) ->
LSF ((pi \&& (var_e x' \= e2), star sig (star (star (singl e1 (var_e x')) (cell (e1 \+ nat_e 1))) (lst (var_e x') e2)))) (x <-* e; c) Q ->
LSF ((pi \&& (var_e x' \!= e2), star sig (star (star (singl e1 (var_e x')) (cell (e1 \+ nat_e 1))) (lst (var_e x') e2)))) (x <-* e; c) Q ->
LSF (pi, star sig (lst e1 e2)) (x <-* e; c) Q.
Local Open Scope frag_list_scope.
Goal
{{{ ((var_e 1 \!= var_e 2) \&& (var_e 1 \!= cst_e 0%Z), lst (var_e 1) (var_e 2)) }}}
0 <-* (var_e 1)
{{{ (true_b, lst (var_e 1) (var_e 2)) }}}.
Proof.
eapply tritra_use.
by compute.
eapply tritra_precond_stre with (((var_e 1 \!= var_e 2) \&& (var_e 1 \!= cst_e 0%Z)), star emp (lst (var_e 1) (var_e 2))).
eapply entail_soundness.
by Entail_turnr; Entail.
eapply tritra_lookup_lst.
intro x; split; omegab.
simpl; intuition.
eapply tritra_precond_stre.
eapply entail_soundness.
Entail_turnl.
Entail_turnl.
Entail_turnl.
Entail_turnl.
eapply entail_id.
eapply tritra_lookup.
intros; omegab.
eapply tritra_subst_elt.
simpl.
eapply tritra_entail.
eapply Decompose_Assrt_interp.
left.
eapply entail_soundness.
Entail_turnr.
eapply entail_lstelim'''.
intros; omegab.
intros; omegab.
intros; omegab.
Entail_turnl.
Entail_turnr.
Entail_turnr.
Entail_turnr.
Entail.
eapply tritra_lookup.
intros; omegab.
eapply tritra_subst_elt.
simpl.
eapply tritra_entail.
eapply Decompose_Assrt_interp.
left.
eapply entail_soundness.
Entail_turnr.
eapply entail_lstelim'''.
intros; omegab.
intros; omegab.
intros; omegab.
Entail_turnl.
Entail_turnr.
Entail_turnr.
Entail_turnr.
Entail.
Qed.
Goal
{{ assrt_interp ((var_e 1 \!= var_e 2) \&& (var_e 1 \!= cst_e 0%Z), lst (var_e 1) (var_e 2))}}
0 <-* (var_e 1)
{{ assrt_interp (true_b, lst (var_e 1) (var_e 2))}}.
eapply LSF_sound.
eapply LSF_add_empty.
eapply LSF_precond_stre with (((var_e 1 \!= var_e 2) \&& (var_e 1 \!= cst_e 0%Z)), star emp (lst (var_e 1) (var_e 2))).
eapply entail_soundness.
Entail_turnr; Entail.
eapply LSF_unroll_lst_lookup'.
intros; omegab.
compute; intuition.
intros; omegab.
eapply LSF_precond_stre with
((var_e 1 \!= var_e 2) \&& (var_e 1 \!= cst_e 0%Z),
star
(star (lst (var_e 3) (var_e 2)) (cell (var_e 1 \+ nat_e 1)))
(singl (var_e 1) (var_e 3))).
eapply entail_soundness.
Entail_turnl.
Entail_turnl.
Entail_turnr.
Entail_turnr.
Entail.
eapply LSF_lookup'.
intros; omegab.
compute; intuition.
eapply LSF_empty.
simpl subst_Sigma.
eapply entail_soundness.
Entail_turnr.
eapply entail_lstelim'''.
intros; omegab.
intros; omegab.
intros; omegab.
Entail_turnl.
Entail_turnr.
Entail_turnr.
eapply entail_lstsamelst.
intros; omegab.
intros; omegab.
simpl.
Entail_turnl.
eapply entail_star_elim''.
intros; omegab.
Entail.
eapply LSF_precond_stre with
((var_e 1 \!= var_e 2) \&& var_e 1 \!= cst_e 0%Z,
star
(star (lst (var_e 3) (var_e 2)) (cell (var_e 1 \+ nat_e 1)))
(singl (var_e 1) (var_e 3))).
eapply entail_soundness.
Entail_turnl.
Entail_turnl.
Entail_turnr.
Entail_turnr.
Entail.
eapply LSF_lookup'.
intros; omegab.
compute; intuition.
eapply LSF_empty.
simpl subst_Sigma.
eapply entail_soundness.
Entail_turnr.
eapply entail_lstelim'''.
intros; omegab.
intros; omegab.
intros; omegab.
Entail_turnl.
Entail_turnr.
Entail_turnr.
eapply entail_lstsamelst.
intros; omegab.
intros; omegab.
simpl.
Entail_turnl.
eapply entail_star_elim''.
intros; omegab.
Entail.
Qed.
Goal
{{ assrt_interp (true_b, emp)}}
If ((var_e 1) \>= (var_e 2)) Then
If (var_e 1 \>= var_e 3) Then
(0 <- var_e 1)
Else
(0 <- (var_e 3))
Else
If (var_e 2 \>= var_e 3) Then
(0 <- (var_e 2))
Else
(0 <- (var_e 3))
{{ assrt_interp (((var_e 0) \= (var_e 1)) \|| ((var_e 0) \= (var_e 2)) \|| ((var_e 0) \= (var_e 3)), emp)}}.
eapply LSF_sound.
eapply LSF_add_empty.
eapply LSF_cond.
eapply LSF_cond.
eapply LSF_assign'.
simpl; intuition.
simpl.
eapply LSF_empty.
eapply entail_soundness; Entail.
eapply LSF_assign'.
simpl; intuition.
simpl.
eapply LSF_empty.
eapply entail_soundness; Entail.
eapply LSF_cond.
eapply LSF_assign'.
simpl; intuition.
simpl.
eapply LSF_empty.
eapply entail_soundness; Entail.
eapply LSF_assign'.
simpl; intuition.
simpl.
eapply LSF_empty.
eapply entail_soundness; Entail.
Qed.
Goal
{{{ (true_b, emp) }}}
If (var_e 1 \>= var_e 2) Then
If (var_e 1 \>= var_e 3) Then
(0 <- var_e 1)
Else
(0 <- var_e 3)
Else
If (var_e 2 \>= var_e 3) Then
(0 <- var_e 2)
Else
(0 <- var_e 3)
{{{ ((var_e 0 \= var_e 1) \|| (var_e 0 \= var_e 2) \|| var_e 0 \= var_e 3,emp) }}}.
Proof.
eapply tritra_use.
simpl.
intuition.
eapply tritra_if.
eapply tritra_if.
eapply tritra_subst_elt.
simpl.
eapply tritra_entail.
eapply Decompose_Assrt_interp; left.
eapply entail_soundness; Entail.
eapply tritra_subst_elt.
simpl.
eapply tritra_entail.
eapply Decompose_Assrt_interp; left.
eapply entail_soundness; Entail.
eapply tritra_if.
eapply tritra_subst_elt.
simpl.
eapply tritra_entail.
eapply Decompose_Assrt_interp; left.
eapply entail_soundness; Entail.
eapply tritra_subst_elt.
simpl.
eapply tritra_entail.
eapply Decompose_Assrt_interp; left.
eapply entail_soundness; Entail.
Qed.
Ltac Rotate_LSF_sig_lhs :=
match goal with
| |- LSF (?pi,?sig) ?c ?Q =>
eapply LSF_precond_stre with (
(pi, remove_empty_heap pi (star_assoc_left (star_com sig) emp))
); [apply entail_soundness; simpl; Entail| simpl]
end.
Section swap.
Definition i : var.v := 1.
Definition j : var.v := 2.
Definition x : var.v := 4.
Definition y : var.v := 3.
Definition vx : var.v := 5.
Definition vy : var.v := 6.
Definition swap (x y:var.v) : @while.cmd cmd0 expr_b :=
i <-* var_e x;
j <-* var_e y;
var_e x *<- var_e j;
var_e y *<- var_e i.
Definition swap_precond (x y:var.v) (vx vy : nat) : assrt :=
(true_b, star (singl (var_e x) (var_e vx)) (singl (var_e y) (var_e vy))).
Definition swap_postcond (x y:var.v) (vx vy : nat) : assrt :=
(true_b, star (singl (var_e x) (var_e vy)) (singl (var_e y) (var_e vx))).
Lemma swap_verif:
{{assrt_interp (swap_precond x y vx vy)}}
swap x y
{{assrt_interp ((swap_postcond x y vx vy))}}.
Proof.
intros.
unfold swap_precond.
unfold swap_postcond.
eapply LSF_sound.
simpl; intuition.
unfold x; unfold y; unfold i; unfold j; unfold vx; unfold vy.
unfold swap.
eapply LSF_add_empty.
repeat (eapply LSF_seq_assoc).
Rotate_LSF_sig_lhs.
eapply LSF_lookup'.
intros; omegab.
simpl; intuition.
simpl.
repeat (eapply LSF_seq_assoc).
Rotate_LSF_sig_lhs.
eapply LSF_lookup'.
intros; omegab.
simpl; intuition.
repeat (eapply LSF_seq_assoc).
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation.
intros; omegab.
Rotate_LSF_sig_lhs.
eapply LSF_mutation.
intros; omegab.
eapply LSF_empty.
eapply entail_soundness.
Entail.
Qed.
Lemma swap_verif':
{{assrt_interp (swap_precond x y vx vy)}}
swap x y
{{Assrt_interp ((swap_postcond x y vx vy)::nil)}}.
Proof.
intros.
unfold swap_precond.
unfold swap_postcond.
eapply tritra_use.
simpl; intuition.
unfold x, y, i, j, vx, vy.
Rotate_tritra_sig_lhs.
eapply tritra_lookup.
intros; omegab.
Rotate_tritra_sig_lhs.
eapply tritra_subst_lookup2.
intros; omegab.
simpl; intuition.
Rotate_tritra_sig_lhs.
eapply tritra_subst_mutation.
simpl.
eapply tritra_mutation.
intros; omegab.
eapply tritra_subst_mutation.
simpl.
Rotate_tritra_sig_lhs.
eapply tritra_mutation.
intros; omegab.
eapply tritra_subst_elt.
simpl.
eapply tritra_entail.
eapply Decompose_Assrt_interp; left.
eapply entail_soundness; Entail.
Qed.
End swap.
Definition ptr : var.v := 1.
Definition startl : var.v := 2.
Definition size: var.v := 3.
Definition idx: var.v := 4.
Definition init_val: var.v := 5.
Fixpoint init_body (n: nat) {struct n}: @while.cmd cmd0 expr_b :=
match n with
0 => skip
| S n' =>
(var_e ptr \+ var_e idx) *<- var_e init_val;
ptr <- var_e ptr \+ var_e size;
init_body n'
end.
Definition init (n: nat) : @while.cmd cmd0 expr_b :=
ptr <- var_e startl;
init_body n.
Fixpoint init_precond_sigma (n: nat) {struct n} : Sigma :=
match n with
0 => emp
| S n' => star
(cell (var_e startl \+ var_e idx \+ var_e size \* cst_e (Z_of_nat n') ))
(init_precond_sigma n')
end.
Definition init_precond (n: nat) : assrt :=
(var_e startl \> cst_e 0%Z, init_precond_sigma n).
Fixpoint init_postcond_sigma (n: nat) {struct n}: Sigma :=
match n with
0 => emp
| S n' => star
(singl (var_e startl \+ var_e idx \+ var_e size \* cst_e (Z_of_nat n')) (var_e init_val))
(init_postcond_sigma n')
end.
Definition init_postcond (n: nat) : assrt :=
(var_e startl \> cst_e 0%Z, init_postcond_sigma n).
Lemma init_verif_bigtoe_5: forall n, n = 5 ->
{{{ init_precond n }}} init n {{{ init_postcond n }}}.
Proof.
intros; subst n.
unfold init; simpl init_body.
unfold init_precond; simpl init_precond_sigma.
unfold init_postcond; simpl init_postcond_sigma.
unfold ptr; unfold startl; unfold size; unfold idx; unfold init_val.
eapply tritra_use.
simpl; intuition.
Tritra.
Qed.
Lemma init_verif_bigtoe_10: forall n, n = 10 ->
{{{ init_precond n }}} init n {{{ init_postcond n }}}.
Proof.
intros; subst n.
unfold init; simpl init_body.
unfold init_precond; simpl init_precond_sigma.
unfold init_postcond; simpl init_postcond_sigma.
unfold ptr, startl, size, idx, init_val.
eapply tritra_use.
simpl; intuition.
Tritra.
Qed.
Lemma init_verif_bigtoe_12: forall n, n = 12 ->
{{{ init_precond n }}} init n {{{ init_postcond n }}}.
Proof.
intros; subst n.
unfold init; simpl init_body.
unfold init_precond; simpl init_precond_sigma.
unfold init_postcond; simpl init_postcond_sigma.
unfold ptr, startl, size, idx, init_val.
eapply tritra_use.
simpl; intuition.
Tritra.
Qed.
Import ZIT.
tactics for cleaning hypothesis
Ltac Decompose_hyp := eval_b2Prop_hyps;
match goal with
| id: ex ?P |- _ => inversion_clear id; Decompose_hyp
| id: ?P1 /\ ?P2 |- _ => decompose [and] id; clear id; Decompose_hyp
| id: eval ?e ?s = ?v |- _ => simpl in id
| |- _ => idtac
end.
Lemma init_verif_smallfoot_5: forall n, n = 5 ->
{{ assrt_interp (init_precond n)}} (init n) {{ assrt_interp (init_postcond n)}}.
Proof.
intros; subst n.
unfold init; simpl init_body.
unfold init_precond; simpl init_precond_sigma.
unfold init_postcond; simpl init_postcond_sigma.
unfold ptr, startl, size, idx, init_val.
eapply LSF_sound.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
intros; omegab.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s H.
Ltac local_omega :=
Decompose_hyp; omegab.
local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s H; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
eapply LSF_empty.
eapply entail_soundness.
Entail.
Qed.
Lemma init_verif_smallfoot_10: forall n, n = 10 ->
{{ assrt_interp (init_precond n)}} init n {{ assrt_interp (init_postcond n)}}.
Proof.
intros; subst n.
unfold init; simpl init_body.
unfold init_precond; simpl init_precond_sigma.
unfold init_postcond; simpl init_postcond_sigma.
unfold ptr, startl, size, idx, init_val.
eapply LSF_sound.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
intros; omegab.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
eapply LSF_empty.
eapply entail_soundness.
Entail.
Qed.
Lemma init_verif_smallfoot_12: forall n, n = 12 ->
{{ assrt_interp (init_precond n)}} (init n) {{ assrt_interp (init_postcond n)}}.
Proof.
intros; subst n.
unfold init; simpl init_body.
unfold init_precond; simpl init_precond_sigma.
unfold init_postcond; simpl init_postcond_sigma.
unfold ptr, startl, size, idx, init_val.
eapply LSF_sound.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
intros; omegab.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
Rotate_LSF_sig_lhs.
eapply LSF_mutation'.
move=> s h; local_omega.
eapply LSF_assign'.
simpl; intuition.
simpl.
eapply LSF_empty.
eapply entail_soundness.
Entail.
Qed.