Require
syntax.
Require
Lattice.
Require
SumLattice.
Require
func.
Require
StackLattice.
Require
AbVal.
Require
FiniteSet.
Require
analysis.
Definition
collect_list_instruction :
(P:Program)MethodName->(list Instruction)->progCount->(list (Constraint P)).
Intros P m l.
NewInduction l; Intros pc.
Exact (nil (Constraint P)).
Exact (app (Flow P m pc a) (IHl (add_un pc))).
Defined
.
Lemma
collect_list_instruction_all :
(P:Program;m:MethodName;l:(list Instruction);pc:progCount;n:nat;I:Instruction)
(nth_error l n)=(Some I) ->
(incl (Flow P m (sub_un (fast_integer.add (anti_convert n) pc)) I)
(collect_list_instruction P m l pc)).
NewInduction l; Simpl.
Destruct n; Simpl; Intros.
Discriminate H.
Discriminate H.
Destruct n; Simpl; Intros.
Injection H; Intros; Clear H; Subst.
Replace (sub_un (fast_integer.add xH pc)) with pc.
Unfold incl; Intros.
Apply in_or_app; Auto.
Rewrite add_sym.
Rewrite <- ZL12.
Rewrite sub_add_one; Auto.
Unfold incl; Intros.
Generalize (IHl (add_un pc) n0 I H a0); Intros.
Apply in_or_app.
Right; Apply H1.
Replace (fast_integer.add (anti_convert n0) (add_un pc)) with (fast_integer.add (add_un (anti_convert n0)) pc); Auto.
Rewrite add_sym.
Rewrite ZL14.
Rewrite ZL14.
Rewrite add_sym; Auto.
Qed
.
Lemma
collect_list_instruction_all_inv :
(P:Program;m:MethodName;l:(list Instruction);pc:progCount;c:(Constraint P))
(In c (collect_list_instruction P m l pc)) ->
(EX n:nat | (EX I:Instruction | (nth_error l n)=(Some I) /\
(In c (Flow P m (sub_un (fast_integer.add (anti_convert n) pc)) I)))).
NewInduction l; Simpl; Intros.
Elim H.
Elim (in_app_or H); Clear H; Intros.
Exists O; Exists a; Simpl ;Split; Auto.
Replace (sub_un (fast_integer.add xH pc)) with pc; Auto.
Rewrite add_sym.
Rewrite <- ZL12.
Rewrite sub_add_one; Auto.
Elim (IHl (add_un pc) c H); Intros n H1.
Elim H1; Clear H1; Intros I (H1,H2).
Exists (S n); Exists I; Simpl; Split; Auto.
Rewrite add_sym.
Rewrite ZL14.
Generalize H2.
Rewrite ZL14.
Rewrite add_sym; Auto.
Qed
.
Definition
collect_list_method :
(P:Program)(list Method)->(list (Constraint P)).
Intros P l.
NewInduction l.
Exact (nil (Constraint P)).
Exact (app (collect_list_instruction P (nameMethod a) (instructions a) xH)
IHl).
Defined
.
Lemma
collect_list_method_all :
(P:Program;m:Method;l:(list Method);pc:progCount;I:Instruction)
(In m l) -> (nth_positive (instructions m) pc)=(Some I) ->
(incl (Flow P (nameMethod m) pc I)
(collect_list_method P l)).
NewInduction l; Simpl; Intros.
Elim H.
Elim H; Clear H; Intros.
Subst.
Generalize H0; Clear H0; Unfold nth_positive; Case pc; Intros.
Generalize (collect_list_instruction_all P (nameMethod m) (instructions m) xH (convert (sub_un (xI p))) ? H0);
Unfold incl; Intros.
Apply in_or_app; Left; Apply H.
Rewrite add_sym.
Rewrite <- ZL12bis.
Rewrite sub_add_one.
Rewrite bij2.
Elim (add_sub_one (xI p)); Intros.
Discriminate H2.
Rewrite H2; Auto.
Generalize (collect_list_instruction_all P (nameMethod m) (instructions m) xH (convert (sub_un (xO p))) ? H0);
Unfold incl; Intros.
Apply in_or_app; Left; Apply H.
Rewrite add_sym.
Rewrite <- ZL12bis.
Rewrite sub_add_one.
Rewrite bij2.
Elim (add_sub_one (xO p)); Intros.
Discriminate H2.
Rewrite H2; Auto.
Generalize (collect_list_instruction_all P (nameMethod m) (instructions m) xH O ? H0);
Unfold incl; Intros.
Apply in_or_app; Left; Apply H.
Simpl; Auto.
Generalize (IHl pc I H H0); Unfold incl; Intros.
Apply in_or_app; Right; Auto.
Qed
.
Lemma
collect_list_method_all_inv :
(P:Program;l:(list Method);c:(Constraint P))
(In c (collect_list_method P l)) ->
(EX pc:progCount| (EX I:Instruction | (EX m:Method |
(In m l) /\ (nth_positive (instructions m) pc)=(Some I) /\
(In c (Flow P (nameMethod m) pc I) )))).
NewInduction l; Simpl; Intros.
Elim H.
Elim (in_app_or H); Clear H; Intros.
Elim (collect_list_instruction_all_inv ? ? ? ? ? H); Intros n; Intros (I,(H1,H2)).
Exists (sub_un (fast_integer.add (anti_convert n) xH)); Exists I; Exists a.
Split; Auto.
Split; Auto.
Rewrite <- ZL12.
Rewrite sub_add_one.
Unfold nth_positive.
Generalize H1; Clear H1.
Case n; Simpl; Auto.
Intros.
CaseEq '(add_un (anti_convert n0)).
Intros.
Rewrite <- H0; Clear H0.
Rewrite sub_add_one.
Rewrite bij1.
Simpl ;Auto.
Intros.
Rewrite <- H0; Clear H0.
Rewrite sub_add_one.
Rewrite bij1.
Simpl ;Auto.
Case (anti_convert n0); Simpl; Intros.
Discriminate H0.
Discriminate H0.
Discriminate H0.
Elim (IHl c H); Intros pc (I,(m,(H1,(H2,H3)))).
Exists pc; Exists I; Exists m; Split; Auto.
Qed
.
Definition
collect : (P:Program) (list (Constraint P)) :=
[P](cons (init_flow P)
(collect_list_method P (methods P))).
Lemma
collect_all :
(P:Program;m:MethodName;pc:progCount;I:Instruction)
(instructionAt P m pc)=(Some I) ->
(incl (Flow P m pc I) (collect P)).
Unfold collect incl instructionAt; Intros P m pc I.
CaseEq '(searchMethod P m); Intros.
Elim (searchMethod_some ? ? ? H); Intros.
Simpl; Right.
Apply (collect_list_method_all P m0 (methods P) pc I); Auto.
Rewrite H3; Auto.
Discriminate H0.
Qed
.
Lemma
collect_all_inv :
(P:Program;c:(Constraint P))
(In c (collect P)) ->
c=(init_flow P) \/
(EX m:MethodName | (EX pc:progCount | (EX I:Instruction |
(instructionAt P m pc)=(Some I)/\
(In c (Flow P m pc I))))).
Unfold collect incl instructionAt; Intros P.
Intros c H; Elim H; Clear H; Intros; Auto.
Right.
Elim (collect_list_method_all_inv ? ? ? H).
Intros pc (I,(m,(H1,(H2,H3)))).
Exists (nameMethod m); Exists pc; Exists I.
Split; Auto.
Rewrite searchMethod_some_inv; Auto.
Qed
.
Lemma
collect_all_valid : (P:Program;c:(Constraint P))
(In c (collect P)) -> (validConstraint P c).
Intros.
Elim (collect_all_inv P c H); Intros.
Rewrite H0; Apply valid_init_flow.
Elim H0; Intros m (pc,(I,(H1,H2))).
Apply (validFlow P m pc I); Auto.
Qed
.
Lemma
verifyAllFlow_verify_collect : (P:Program;AbS:(AbState P))
((c:(Constraint P))
(In c (collect P))->
(verifyContraint P AbS c) ) ->
(verifyAllFlow P AbS).
Unfold verifyAllFlow; Intros; Split.
Apply H; Unfold collect; Left; Auto.
Unfold verifyFlow; Intros; Apply H.
Apply (collect_all ? ? ? ? H0); Auto.
Qed
.
Lemma
verify_collect_verifyAllFlow : (P:Program;AbS:(AbState P))
(verifyAllFlow P AbS) ->
((c:(Constraint P))
(In c (collect P))->
(verifyContraint P AbS c)).
Unfold verifyAllFlow; Intros.
Elim H; Clear H; Intros.
Elim (collect_all_inv ? ? H0); Intros.
Subst; Auto.
Do 4 (Elim H2; Clear H2; Intros).
Generalize (H1 ? ? ? H2); Unfold verifyFlow.
Auto.
Qed
.
Definition
substBotStack : (P:Program)Address->(AbStack P)->(AbState P):=
[P,add,s]
(bottom (LatAbHeap P),
(bottom (LatAbFuncLocalVar P),
(subst (LatAbFuncPcStack P)
(bottom (LatAbFuncStack P))
(mAdd add)
(subst (LatAbStack P)
(apply (LatAbFuncPcStack P) (bottom (LatAbFuncStack P)) (mAdd add))
(pcAdd add) s)))).
Definition
substBotLocalVar : (P:Program)Address->(AbLocalVar P)->(AbState P):=
[P,add,l]
(bottom (LatAbHeap P),
((subst (LatAbFuncPcLocalVar P)
(bottom (LatAbFuncLocalVar P))
(mAdd add)
(subst (LatAbLocalVar P)
(apply (LatAbFuncPcLocalVar P) (bottom (LatAbFuncLocalVar P)) (mAdd add))
(pcAdd add) l)),bottom (LatAbFuncStack P))).
Definition
apply_Constraint : (P:Program;c:(Constraint P);AbS:(AbState P))(AbState P) :=
[P,c]Cases c of
| (c2S add_out S0) => [AbS](substBotStack P add_out S0)
| (c2H H0) => [AbS](H0,(bottom (LatAbFrame P)))
| (S2S add_in add_out F) => [AbS]let (_,SF)=AbS in let (_,S)=SF in
(substBotStack P add_out (F (S add_in)))
| (L2L add_in add_out F) => [AbS]let (_,SF)=AbS in let (L,_)=SF in
(substBotLocalVar P add_out (F (L add_in)))
| (SL2S add_in add_out F) => [AbS]let (_,SF)=AbS in let (L,S)=SF in
(substBotStack P add_out (F (S add_in) (L add_in)))
| (SL2L add_in add_out F) => [AbS]let (_,SF)=AbS in let (L,S)=SF in
(substBotLocalVar P add_out (F (S add_in) (L add_in)))
| (HS2S add_in add_out F) => [AbS]let (H,SF)=AbS in let (_,S)=SF in
(substBotStack P add_out (F H (S add_in)))
| (S2H add_in F) => [AbS]let (_,SF)=AbS in let (_,S)=SF in
((F (S add_in)),bottom (LatAbFrame P))
| (S2allS add_in F) => [AbS]let (_,SF)=AbS in let (_,S)=SF in
(bottom (LatAbHeap P),(bottom (LatAbFuncLocalVar P),(F (S add_in))))
| (S2allL add_in F) => [AbS]let (_,SF)=AbS in let (_,S)=SF in
(bottom (LatAbHeap P),(F (S add_in),bottom (LatAbFuncStack P)))
| (allS2S add_out F) => [AbS]let (_,SF)=AbS in let (_,S)=SF in
(substBotStack P add_out (F S))
end.
Lemma
apply_Constraint_order : (P:Program;c:(Constraint P);AbS:(AbState P))
(validConstraint P c) ->
(order (LatAbState P) (apply_Constraint P c AbS) AbS) ->
(verifyContraint P AbS c).
Intros P c (H,(L,S)).
Case c; Cbv Beta Iota Delta [apply_Constraint validConstraint];
Unfold substBotStack substBotLocalVar; Intros;
Elim H1; Cbv Beta Iota Delta [fst snd]; Clear H1; Intros;
Elim H2; Cbv Beta Iota Delta [fst snd]; Clear H2; Intros.
Elim H0; Clear H0; Intros.
Apply (verify_c2S P); Unfold applyL applyS.
Generalize (subst_order_inf ? ? ? ? ? ? ? H0 H3); Intros.
Apply (subst_order_inf ? ? ? ? ? ? ? H4 H5); Auto.
Apply (verify_c2H P); Auto.
Apply (verify_S2S P); Unfold applyS.
Elim H0; Clear H0; Intros.
Generalize (subst_order_inf ? ? ? ? ? ? ? H0 H3); Intros.
Apply (subst_order_inf ? ? ? ? ? ? ? H4 H5); Auto.
Apply (verify_L2L P); Unfold applyL.
Elim H0; Clear H0; Intros.
Generalize (subst_order_inf ? ? ? ? ? ? ? H0 H2); Intros.
Apply (subst_order_inf ? ? ? ? ? ? ? H4 H5); Auto.
Apply (verify_SL2S P); Unfold applyL applyS.
Elim H0; Clear H0; Intros.
Generalize (subst_order_inf ? ? ? ? ? ? ? H0 H3); Intros.
Apply (subst_order_inf ? ? ? ? ? ? ? H4 H5); Auto.
Apply (verify_SL2L P); Unfold applyL applyS.
Elim H0; Clear H0; Intros.
Generalize (subst_order_inf ? ? ? ? ? ? ? H0 H2); Intros.
Apply (subst_order_inf ? ? ? ? ? ? ? H4 H5); Auto.
Apply (verify_HS2S P); Unfold applyL applyS.
Elim H0; Clear H0; Intros.
Generalize (subst_order_inf ? ? ? ? ? ? ? H0 H3); Intros.
Apply (subst_order_inf ? ? ? ? ? ? ? H4 H5); Auto.
Apply (verify_S2H P); Auto.
Apply (verify_S2allS P); Auto.
Apply (verify_S2allL P); Auto.
Apply (verify_allS2S P); Unfold applyL applyS.
Elim H0; Clear H0; Intros.
Generalize (subst_order_inf ? ? ? ? ? ? ? H0 H3); Intros.
Apply (subst_order_inf ? ? ? ? ? ? ? H4 H5); Auto.
Qed
.
Lemma
apply_Constraint_order_inv : (P:Program;c:(Constraint P);AbS:(AbState P))
(verifyContraint P AbS c) ->
(order (LatAbState P) (apply_Constraint P c AbS) AbS).
Intros P c (H,(L,S)).
Case c; Cbv Beta Iota Delta [apply_Constraint]; Intros;
Inversion_clear H0; Unfold substBotLocalVar substBotStack;
Split; Cbv Beta Iota Delta [fst snd]; Auto;
Split; Cbv Beta Iota Delta [fst snd]; Auto;
Try (
Apply (subst_order ? (LatAbFuncPcStack P) (max_log_MethodName P)); Intros;
[Apply apply_monotone; Auto|
Apply (subst_order ? (LatAbStack P) (max_log_pc P)); Intros;
[Apply apply_monotone; Auto|Auto]]; Fail);
Try (
Apply (subst_order ? (LatAbFuncPcLocalVar P) (max_log_MethodName P)); Intros;
[Apply apply_monotone; Auto|
Apply (subst_order ? (LatAbLocalVar P) (max_log_pc P)); Intros;
[Apply apply_monotone; Auto|Auto]];Fail).
Qed
.
Definition
collect_func : (P:Program)(list (AbState P)->(AbState P)) :=
[P](PolyList.map (apply_Constraint P) (collect P)).
Lemma
fix_apply_list_collect1 : (P:Program;AbS:(AbState P))
((f:(AbState P)->(AbState P)) (In f (collect_func P)) ->
(order (LatAbState P) (f AbS) AbS)) ->
(verifyAllFlow P AbS).
Intros.
Apply verifyAllFlow_verify_collect; Intros.
Apply apply_Constraint_order.
Apply collect_all_valid; Auto.
Unfold collect_func in H.
Apply H.
Apply PolyList.in_map; Auto.
Qed
.
Lemma
in_map2 : (A,B:Set)(l:(list A);f:A->B;y:B)
(In y (PolyList.map f l)) ->
(EX x:A | y=(f x) /\ (In x l)).
NewInduction l; Simpl; Intros; Intuition.
Exists a; Auto.
Elim (IHl f y H0); Intuition.
Exists x; Auto.
Qed
.
Lemma
fix_apply_list_collect2 : (P:Program;AbS:(AbState P))
(verifyAllFlow P AbS) ->
(f:(AbState P)->(AbState P)) (In f (collect_func P)) ->
(order (LatAbState P) (f AbS) AbS).
Unfold collect_func; Intros.
Elim (in_map2 ? ? ? ? ? H0); Intuition.
Subst.
Apply apply_Constraint_order_inv.
Apply verify_collect_verifyAllFlow; Auto.
Qed
.
Definition
apply_list_func :
(P:Program)(list (AbState P)->(AbState P))->(AbState P)->(AbState P) :=
[P,l,AbS]
(join_list ? (LatAbState P) (PolyList.map [f](f AbS) l)).
Definition
Flow_func : (P:Program)(AbState P)->(AbState P) :=
[P](apply_list_func P (collect_func P)).
Lemma
fix_apply_list_func1 : (P:Program;AbS:(AbState P))
(order (LatAbState P) (Flow_func P AbS) AbS) ->
(verifyAllFlow P AbS).
Unfold Flow_func apply_list_func; Intros.
Apply verifyAllFlow_verify_collect; Intros.
Apply apply_Constraint_order.
Apply collect_all_valid; Auto.
Apply order_trans with (join_list (AbState P) (LatAbState P)
(PolyList.map [f:((AbState P)->(AbState P))](f AbS)
(collect_func P))); Auto.
Apply join_list_greater.
Unfold collect_func.
Apply PolyList.in_map with f:=[f:((AbState P)->(AbState P))](f AbS).
Apply PolyList.in_map; Auto.
Qed
.
Lemma
fix_apply_list_func2 : (P:Program;AbS:(AbState P))
(verifyAllFlow P AbS) ->
(order (LatAbState P) (Flow_func P AbS) AbS).
Unfold Flow_func apply_list_func; Intros.
Apply join_list_least_greater; Intros.
Elim (in_map2 ? ? ? ? ? H0); Intuition.
Unfold collect_func in H3.
Elim (in_map2 ? ? ? ? ? H3); Intuition.
Subst.
Apply apply_Constraint_order_inv.
Apply verify_collect_verifyAllFlow; Auto.
Qed
.
Lemma
substBotStack_monotone : (P:Program;ad:Address;S1,S2:(AbStack P))
(order (LatAbStack P) S1 S2) ->
(order (LatAbState P) (substBotStack P ad S1) (substBotStack P ad S2)).
Unfold substBotStack; Intros.
Split; Auto.
Split; Auto.
Cbv Beta Iota Delta [fst snd].
Apply (subst_monotone ? (LatAbFuncPcStack P) (max_log_MethodName P)); Auto.
Apply (subst_monotone ? (LatAbStack P) (max_log_pc P)); Auto.
Qed
.
Lemma
substBotLocalVar_monotone : (P:Program;ad:Address;S1,S2:(AbLocalVar P))
(order (LatAbLocalVar P) S1 S2) ->
(order (LatAbState P) (substBotLocalVar P ad S1) (substBotLocalVar P ad S2)).
Unfold substBotLocalVar; Intros.
Split; Auto.
Split; Auto.
Cbv Beta Iota Delta [fst snd].
Apply (subst_monotone ? (LatAbFuncPcLocalVar P) (max_log_MethodName P)); Auto.
Apply (subst_monotone ? (LatAbLocalVar P) (max_log_pc P)); Auto.
Qed
.
Lemma
constraint_monotone_prop : (P:Program;c:(Constraint P))
(constraint_monotone P c) ->
(AbS1,AbS2:(AbState P))
(order (LatAbState P) AbS1 AbS2) ->
(order (LatAbState P) (apply_Constraint P c AbS1)
(apply_Constraint P c AbS2)).
Destruct AbS1; Intros H1 SF1.
Destruct AbS2; Intros H2 SF2.
Case SF1; Intros L1 S1.
Case SF2; Intros L2 S2; Intros.
Elim H0; Cbv Beta Iota Delta [fst snd].
Clear H0; Intros.
Elim H3; Cbv Beta Iota Delta [fst snd].
Clear H3; Intros.
Inversion_clear H; Unfold apply_Constraint.
Auto.
Auto.
Apply substBotStack_monotone; Apply H5.
Unfold applyS; Do 2 Apply apply_monotone; Assumption.
Apply substBotLocalVar_monotone; Apply H5.
Unfold applyL; Do 2 Apply apply_monotone; Assumption.
Apply substBotStack_monotone; Apply H5.
Unfold applyS; Do 2 Apply apply_monotone; Assumption.
Unfold applyL; Do 2 Apply apply_monotone; Assumption.
Apply substBotLocalVar_monotone; Apply H5.
Unfold applyS; Do 2 Apply apply_monotone; Assumption.
Unfold applyL; Do 2 Apply apply_monotone; Assumption.
Apply substBotStack_monotone; Apply H5.
Assumption.
Unfold applyS; Do 2 Apply apply_monotone; Assumption.
Split; Cbv Beta Iota Delta [fst snd].
Apply H5; Unfold applyS; Do 2 Apply apply_monotone; Assumption.
Auto.
Split; Cbv Beta Iota Delta [fst snd].
Apply bottom_is_a_bottom.
Split; Cbv Beta Iota Delta [fst snd].
Apply bottom_is_a_bottom.
Apply H5; Unfold applyS; Do 2 Apply apply_monotone; Assumption.
Split; Cbv Beta Iota Delta [fst snd].
Apply bottom_is_a_bottom.
Split; Cbv Beta Iota Delta [fst snd].
Apply H5; Unfold applyS; Do 2 Apply apply_monotone; Assumption.
Apply bottom_is_a_bottom.
Apply substBotStack_monotone; Apply H5.
Auto.
Qed
.
Lemma
collect_monotone : (P:Program;c:(Constraint P))
(In c (collect P)) -> (constraint_monotone P c).
Intros.
Elim (collect_all_inv ? ? H); Intros.
Subst; Unfold init_flow; Constructor.
Do 4 (Elim H0; Clear H0; Intros).
Apply monotone_Flow with x x0 x1; Auto.
Qed
.
Lemma
app_map : (A,B:Set;f:A->B;l1,l2:(list A))
(app (PolyList.map f l1) (PolyList.map f l2))=(PolyList.map f (app l1 l2)).
NewInduction l1; Simpl; Auto.
Intros.
Rewrite IHl1; Auto.
Qed
.
Lemma
rev_map : (A,B:Set;f:A->B;l:(list A))
(rev (PolyList.map f l))=(PolyList.map f (rev l)).
NewInduction l; Simpl; Auto.
Rewrite IHl.
Generalize (app_map ? ? f (rev l) (cons a (nil A))); Simpl; Intros.
Rewrite H; Auto.
Qed
.
Lemma
collect_func_monotone : (P:Program)(f:(AbState P)->(AbState P))
(In f (rev (collect_func P))) ->
(AbS1,AbS2:(AbState P))
(order (LatAbState P) AbS1 AbS2) ->
(order (LatAbState P) (f AbS1) (f AbS2)).
Unfold collect_func; Intros.
Generalize (in_rev ? (rev (PolyList.map (apply_Constraint P) (collect P)))).
Rewrite idempot_rev.
Intros.
Generalize (H1 ? H); Intros.
Elim (in_map2 ? ? ? ? ? H2); Intros.
Decompose [and] H3; Clear H3.
Subst.
Apply constraint_monotone_prop; Auto.
Apply collect_monotone; Auto.
Qed
.
Lemma
Flow_func_monotone : (P:Program;AbS1,AbS2:(AbState P))
(order (LatAbState P) AbS1 AbS2) ->
(order (LatAbState P) (Flow_func P AbS1) (Flow_func P AbS2)).
Unfold Flow_func apply_list_func; Intros.
Apply join_list_least_greater; Intros.
Elim (in_map2 ? ? ? ? ? H0); Intros.
Decompose [and] H1; Clear H1.
Unfold collect_func in H3.
Elim (in_map2 ? ? ? ? ? H3); Intros.
Decompose [and] H1; Clear H1.
Subst.
Apply order_trans with (apply_Constraint P x1 AbS2).
Apply constraint_monotone_prop; Auto.
Apply collect_monotone; Auto.
Apply join_list_greater.
Apply in_map with f:=([f:((AbState P)->(AbState P))](f AbS2)).
Unfold collect_func; Auto.
Qed
.
Definition
analyzer : (P:Program)(AbState P) :=
[P](lfp (AbState P) (LatAbState P) (Flow_func P) (Flow_func_monotone P)).
Definition
analyzer_list : (P:Program)(AbState P) :=
[P](lfp_list (AbState P) (LatAbState P)
(collect_func P)
(collect_func_monotone P)).