Theory PhiSem_Formalization_Tools

theory PhiSem_Formalization_Tools
  imports IDE_CP
  keywords ":=" :: quasi_command
begin

section ‹Tools for Formalizing Instructions›

named_theorems discharging_semantic_debt
  ‹Theorems that discharges or helps to discharge the debt axioms for semantic formalization.›

subsection ‹Elementary Constructions for Formalizing Instructions›

definition semantic_literal = φarg

notation (do_notation) semantic_literal ("𝗅𝗂𝗍𝖾𝗋𝖺𝗅")

ML Synchronized.change Phi_Syntax.semantic_oprs (Symtab.update (const_namesemantic_literal, 0))

definition φM_assert :: bool  unit proc
  where φM_assert P = (λs. if P then Return φV_none s else {Invalid})

definition φM_assume :: bool  unit proc
  where φM_assume P = (λs. if P then Return φV_none s else {AssumptionBroken})

definition φM_getV_raw :: (VAL  'v)  VAL φarg  ('v  'y proc)  'y proc
  where φM_getV_raw VDT_dest v F = F (VDT_dest (φarg.dest v))

definition φM_getV :: TY  (VAL  'v)  VAL φarg  ('v  'y proc)  'y proc
  where φM_getV TY VDT_dest v F =
    (φM_assert (φarg.dest v  Well_Type TY)  F (VDT_dest (φarg.dest v)))

definition φM_caseV :: (VAL φarg  ('vr,'ret) proc')  (VAL × 'vr::FIX_ARITY_VALs,'ret) proc'
  where φM_caseV F = (λarg. case arg of φarg (a1,a2)  F (φarg a1) (φarg a2))


lemma Valid_Proc_φM_assert[intro!, φreason 1200]:
  Valid_Proc (φM_assert P)
  unfolding Valid_Proc_def φM_assert_def Return_def det_lift_def
  by clarsimp

lemma Valid_Proc_φM_assume[intro!, φreason 1200]:
  Valid_Proc (φM_assume P)
  unfolding Valid_Proc_def φM_assume_def Return_def det_lift_def
  by clarsimp

lemma Valid_Proc_φM_getV_raw[intro!, φreason 1200]:
  (v. Valid_Proc (F v))
 Valid_Proc (φM_getV_raw VDF v F)
  unfolding Valid_Proc_def φM_getV_raw_def
  by blast

(*to depreciate the above!*)

subsection ‹Basic Rules›

declare φSEQ[intro!]

lemma φM_assert[intro!]:
  (Satisfiable X  P)  𝗉𝗋𝗈𝖼 φM_assert P  X  λ_. X  𝗍𝗁𝗋𝗈𝗐𝗌 Any
  unfolding φM_assert_def
  by (rule φSatisfiable; simp; rule)

lemma semantic_assert_φapp:
  𝗉𝖺𝗋𝖺𝗆 P
 𝗉𝗋𝖾𝗆𝗂𝗌𝖾 P
 𝗉𝗋𝗈𝖼 φM_assert P  X  λ_. X 
  unfolding φM_assert_def Premise_def
  by (simp; rule)

lemma φM_assert_True[simp]:
  φM_assert True = Return φV_none
  unfolding φM_assert_def by simp

lemma φM_assert':
  P  Q (F args)  Q ((φM_assert P  F) args)
  unfolding φM_assert_def bind_def Return_def det_lift_def by simp

lemma φM_assume[intro!]:
  (P  𝗉𝗋𝗈𝖼 F  X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E)  𝗉𝗋𝗈𝖼 (φM_assume P  F)  X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E
  unfolding φProcedure_def φM_assume_def bind_def Return_def det_lift_def less_eq_BI_iff
  by clarsimp

lemma φM_assume1[intro!]:
  𝗉𝗋𝗈𝖼 (φM_assume P)  Void  Void 𝗌𝗎𝖻𝗃 P  𝗍𝗁𝗋𝗈𝗐𝗌 E
  unfolding φM_assume_def φProcedure_def bind_def Return_def det_lift_def less_eq_BI_iff
  by clarsimp

lemma semantic_assumption_φapp:
  𝗉𝖺𝗋𝖺𝗆 P
 𝗉𝗋𝗈𝖼 (φM_assume P)  Void  Void 𝗌𝗎𝖻𝗃 P 
  using φM_assume1 .

lemma φM_tail_left:  𝗉𝗋𝗈𝖼 F  X 1  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E  𝗉𝗋𝗈𝖼 F  X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E by simp
lemma φM_tail_right: 𝗉𝗋𝗈𝖼 F  X  λv. Y v 1  𝗍𝗁𝗋𝗈𝗐𝗌 E  𝗉𝗋𝗈𝖼 F  X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E by simp
lemma φM_shrink_left:  𝗉𝗋𝗈𝖼 F  X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E  𝗉𝗋𝗈𝖼 F  X 1  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E by simp
lemma φM_shrink_right[intro!]: 𝗉𝗋𝗈𝖼 F  X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E  𝗉𝗋𝗈𝖼 F  X  λv. Y v 1  𝗍𝗁𝗋𝗈𝗐𝗌 E by simp

lemma φM_getV_raw[intro!]:
   (v  (x  A)  𝗉𝗋𝗈𝖼 F (VDT_dest v)  X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E  )
 𝗉𝗋𝗈𝖼 φM_getV_raw VDT_dest (φarg v) F  x  Val (φarg v) A X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E
  unfolding φM_getV_raw_def Premise_def
  by (clarsimp simp add: Val.unfold norm_precond_conj)

declare φM_getV_raw[where X=1, simplified, intro!]

lemma φM_getV[intro!]:
   (v  (x  A)  <φexpn> v  Well_Type TY)
 (v  (x  A)  𝗉𝗋𝗈𝖼 F (VDT_dest v)  X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E  )
 𝗉𝗋𝗈𝖼 φM_getV TY VDT_dest (φarg v) F  x  Val (φarg v) A X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E
  unfolding φM_getV_def Premise_def
  by (clarsimp simp add: Val.unfold norm_precond_conj)

declare φM_getV[where X=1, simplified, intro!]

lemma φM_caseV[intro!]:
  𝗉𝗋𝗈𝖼 F va vb  X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E
 𝗉𝗋𝗈𝖼 φM_caseV F (φV_pair va vb)  X  Y  𝗍𝗁𝗋𝗈𝗐𝗌 E
  unfolding φM_caseV_def φV_pair_def by simp

(*to depreciate the above!*)


lemma "__Return_rule__":
  𝗉𝗋𝗈𝖼 Return v  X v  X 
  unfolding φProcedure_def det_lift_def Return_def less_eq_BI_iff
  by clarsimp

lemma semantic_return_φapp:
  𝗉𝖺𝗋𝖺𝗆 (v  (y  T))
 𝗉𝗋𝖾𝗆𝗂𝗌𝖾 v  (y  T)
 𝗉𝗋𝗈𝖼 Return (φarg v)  X  λu. y  Val u T X 
  unfolding Premise_def φProcedure_def det_lift_def Return_def less_eq_BI_iff
  by (clarsimp simp add: Val.unfold)

lemma semantic_literal_φapp:
  𝗉𝖺𝗋𝖺𝗆 (v  (y  T))
 𝗉𝗋𝖾𝗆𝗂𝗌𝖾 v  (y  T)
 Void 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 y  Val (semantic_literal v) T
  unfolding Premise_def Transformation_def semantic_literal_def
  by clarsimp

lemma semantic_local_value_φapp:
  𝗉𝖺𝗋𝖺𝗆 TY
 Semantic_Type' (x  T) TY
 𝗉𝗋𝗈𝖼 φM_assert (φarg.dest v  Well_Type TY)  x  𝗏𝖺𝗅[v] T  λ_. Void 𝗌𝗎𝖻𝗃 φarg.dest v  (x  T) 
  unfolding φM_assert_def Premise_def Semantic_Type'_def subset_iff φProcedure_def det_lift_def Return_def
  by (clarsimp simp add: Val.unfold INTERP_SPEC less_eq_BI_iff)

lemma semantic_local_values_nochk_φapp:
  x  𝗏𝖺𝗅𝗌[v] T 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 Void 𝗐𝗂𝗍𝗁 φarg.dest v  (x  T)
  unfolding Transformation_def
  by clarsimp


lemma semantic_local_value_nochk_φapp:
  x  𝗏𝖺𝗅[v] T 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 1 𝗐𝗂𝗍𝗁 φarg.dest v  (x  T)
  unfolding Transformation_def
  by clarsimp

subsection ‹Synthesis of Value›

subsubsection ‹Literal Value›

definition [φprogramming_simps]: literal x  x ― ‹tagging to synthesis a literal›

declare [[φreason_default_pattern
      ?X 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 ?y  𝗏𝖺𝗅[semantic_literal _] ?T 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 _ @tag synthesis 
      ?X 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 ?y  𝗏𝖺𝗅[semantic_literal _] ?T 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 _ @tag synthesis
      ?X 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 ?y  𝗏𝖺𝗅[semantic_literal _]  _ 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 _ @tag synthesis    (500) ]]

setup Context.theory_map (
  Phi_Reasoner.add_pass
      (Const("Phi_Type_of_Literal.synthesisable_literals", dummyT),
       pattern_prop?X 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 ?y  𝗏𝖺𝗅[semantic_literal _] ?T 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 _ @tag synthesis,
       fn pos => fn (rules, prio, patterns, guard, ctxt) =>
          let val T_names =
                     fold ((fn Const(const_nameREMAINS, _) $ (
                                  Const(const_nameφType, _) $ _
                                    $ (Const(const_nameVal, _) $ _ $ T)) $ _ =>
                                 (case Term.head_of T
                                    of Const(N, _) => insert (op =) N
                                     | _ => I)
                             | _ => I)
                           o #2 o Phi_Syntax.dest_transformation o Thm.concl_of) rules []
           in if null T_names then ()
                 else Synchronized.change Phi_Type_of_Literal.synthesisable_literals
                                          (fold Symtab.insert_set T_names);
              (rules, prio, patterns, guard, ctxt)
          end
       )
)

lemma "_synthesis_literal_":
  R 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 const  𝗏𝖺𝗅[semantic_literal v] T 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 R' @tag synthesis
 𝗉𝗋𝗈𝖼 Return (semantic_literal v)  R  λret. const  𝗏𝖺𝗅[ret] T 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 R'  @tag synthesis
  unfolding Action_Tag_def Premise_def φProcedure_def det_lift_def Return_def semantic_literal_def Transformation_def
  by (clarsimp simp add: Val.unfold INTERP_SPEC_subj less_eq_BI_iff INTERP_SPEC, blast)

lemmas [φreason %φsynthesis_literal] = "_synthesis_literal_"[where const=literal x for x]

lemma [φreason %is_literal]:
  Is_Literal (literal x)
  unfolding Is_Literal_def ..



subsubsection ‹Value Sequence›

lemma semantic_cons_lval_φapp:
  𝗉𝗋𝗈𝖼 Return (φV_cons vh vL)  xh  𝗏𝖺𝗅[vh] T xL  𝗏𝖺𝗅𝗌[vL] L  λret. (xh, xL)  𝗏𝖺𝗅𝗌[ret] (List_Item T  L) 
  unfolding Premise_def φProcedure_def det_lift_def Return_def
  by (cases vh; cases vL; clarsimp simp add: Val.unfold Vals.unfold times_list_def less_eq_BI_iff,
      smt (verit, ccfv_threshold) append_Cons append_Nil list.inject)

lemma semantic_cons_lval1_φapp:
  𝗉𝗋𝗈𝖼 Return (φV_cons v φV_nil)  x  𝗏𝖺𝗅[v] T  λret. x  𝗏𝖺𝗅𝗌[ret] List_Item T 
  unfolding Premise_def φProcedure_def det_lift_def Return_def
  by (cases v; clarsimp simp add: Val.unfold Vals.unfold times_list_def less_eq_BI_iff)


proc (nodef) [φreason %φsynthesis_cut
                  for 𝗉𝗋𝗈𝖼 _  _  λret. (_, _)  𝗏𝖺𝗅𝗌[ret] (List_Item _  _) 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 _  @tag synthesis]:
  requires C1: 𝗉𝗋𝗈𝖼 C1  R0  λret. xh  𝗏𝖺𝗅[ret] T 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 R1  @tag synthesis
       and C2: 𝗉𝗋𝗈𝖼 C2  R1  λret. xL  𝗏𝖺𝗅𝗌[ret] L 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 R2  @tag synthesis
  input  R0
  output λret. (xh, xL)  𝗏𝖺𝗅𝗌[ret] (List_Item T  L) 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 R2
  @tag synthesis

  C1  val h 
  C2 $h semantic_cons_lval
 .


proc (nodef) [φreason %φsynthesis_cut
                  for 𝗉𝗋𝗈𝖼 _  _  λret. _  𝗏𝖺𝗅𝗌[ret] (List_Item _) 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 _  @tag synthesis]:
  requires C: 𝗉𝗋𝗈𝖼 C  R0  λret. xh  𝗏𝖺𝗅[ret] T 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 R1  @tag synthesis
  input  R0
  output λret. xh  𝗏𝖺𝗅𝗌[ret] List_Item T 𝗋𝖾𝗆𝖺𝗂𝗇𝗌 R1
  @tag synthesis

  C semantic_cons_lval1
 .

lemma [φreason %φsynthesis_cut
           for 𝗉𝗋𝗈𝖼 _  _  λret. ()  𝗏𝖺𝗅𝗌[ret]  𝗋𝖾𝗆𝖺𝗂𝗇𝗌 _  @tag synthesis]:
  𝗉𝗋𝗈𝖼 Return φV_nil  R0  λret. ()  𝗏𝖺𝗅𝗌[ret]  𝗋𝖾𝗆𝖺𝗂𝗇𝗌 R0 
  unfolding Premise_def φProcedure_def det_lift_def Return_def REMAINS_def
  by (clarsimp simp add: Val.unfold Vals.unfold times_list_def less_eq_BI_iff)





subsection ‹Drop & Duplicate Value›

lemma [φreason 1200 for ?x  Val ?raw ?T 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 ?Y 𝗐𝗂𝗍𝗁 ?P @tag action_dup]:
  x  Val raw T 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 x  Val raw T  x  Val raw T @tag action_dup
  unfolding Transformation_def Action_Tag_def
  by (clarsimp simp add: Val.unfold INTERP_SPEC less_eq_BI_iff)

lemma [φreason 1200 for ?x  Val ?raw ?T ?R 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 ?Y 𝗐𝗂𝗍𝗁 ?P @tag action_drop]:
  x  Val raw T Void 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 Void @tag action_drop
  unfolding Transformation_def Action_Tag_def
  by (clarsimp simp add: Val.unfold)


subsection ‹Abnormal›

definition throw :: ABNM  'ret proc
  where throw raw = det_lift (Abnormal raw)

lemma throw_reduce_tail[procedure_simps,simp]:
  (throw any  f) = throw any
  unfolding throw_def bind_def det_lift_def by simp

lemma "__throw_rule__"[intro!]:
  (a. X a 𝗍𝗋𝖺𝗇𝗌𝖿𝗈𝗋𝗆𝗌 X' a)
 𝗉𝗋𝗈𝖼 (throw excep :: 'ret proc)  X excep  Any  𝗍𝗁𝗋𝗈𝗐𝗌 X'
  unfolding φProcedure_def subset_iff det_lift_def throw_def Transformation_def
  by (clarsimp simp add: INTERP_SPEC less_eq_BI_iff; metis)

lemma throw_φapp:
  𝗉𝖺𝗋𝖺𝗆 excep
 lambda_abstraction excep XX X
 (v. Remove_Values (X v) (X' v))
 𝗉𝗋𝗈𝖼 throw excep  XX  0  𝗍𝗁𝗋𝗈𝗐𝗌 X'
  unfolding φProcedure_def subset_iff det_lift_def throw_def Remove_Values_def Transformation_def
            lambda_abstraction_def
  by (clarsimp simp add: INTERP_SPEC less_eq_BI_iff, metis)

definition op_try :: "'ret proc  (ABNM  'ret proc)  'ret proc"
  where op_try f g s = ((λy. case y of Success x s'  {Success x s'}
                                       | Abnormal v s'  g v s'
                                       | AssumptionBroken  {AssumptionBroken}
                                       | NonTerm  {NonTerm}
                                       | Invalid  {Invalid}) ` f s)

lemma "__op_try__"[intro!]:
  𝗉𝗋𝗈𝖼 f  X  Y1  𝗍𝗁𝗋𝗈𝗐𝗌 (λv. E v)
 (v. 𝗉𝗋𝗈𝖼 g v  E v  Y2  𝗍𝗁𝗋𝗈𝗐𝗌 E2 )
 𝗉𝗋𝗈𝖼 op_try f g  X  λv. Y1 v + Y2 v  𝗍𝗁𝗋𝗈𝗐𝗌 E2
  unfolding op_try_def φProcedure_def less_eq_BI_iff
  apply clarsimp subgoal for comp R x s
    apply (cases s; simp; cases x; clarsimp simp add: INTERP_SPEC set_mult_expn ring_distribs)
    subgoal premises prems for a b u v
      using prems(1)[THEN spec[where x=comp], THEN spec[where x=R]]
      by (metis (no_types, lifting) INTERP_SPEC LooseState_expn(1) prems(3) prems(6) prems(7) prems(8) prems(9) sep_conj_expn)
    subgoal premises prems for a b c d u v2 proof -
      have Abnormal a b  LooseState (λv. INTERP_SPEC (Y1 v R)) (λv. INTERP_SPEC (E v R))
        using prems(1)[THEN spec[where x=comp], THEN spec[where x=R]]
        using prems(10) prems(3) prems(7) prems(8) prems(9) by blast
      note this[simplified]
      then have Success c d  LooseState (λv. INTERP_SPEC (Y2 v R)) (λv. INTERP_SPEC (E2 v R))
        using prems(2)[of a, THEN spec[where x=b], THEN spec[where x=R]]
        by (meson INTERP_SPEC prems(4) sep_conj_expn)
      note this[simplified]
      then show ?thesis
        by (metis INTERP_SPEC prems(11) sep_conj_expn)
    qed
    subgoal premises prems for a b c d u v proof -
      have Abnormal a b  LooseState (λv. INTERP_SPEC (Y1 v R)) (λv. INTERP_SPEC (E v R))
        using prems(1)[THEN spec[where x=comp], THEN spec[where x=R]]
        using prems(10) prems(3) prems(7) prems(8) prems(9) by blast
      note this[simplified]
      then have Abnormal c d  LooseState (λv. INTERP_SPEC (Y2 v R)) (λv. INTERP_SPEC (E2 v R))
        using prems(2)[THEN spec[where x=b], THEN spec[where x=R]]
        by (meson INTERP_SPEC prems(4) sep_conj_expn)
      note this[simplified]
      then show ?thesis
        by (simp add: INTERP_SPEC set_mult_expn)
    qed
     apply (smt (z3) INTERP_SPEC LooseState_expn(2) LooseState_expn(3) sep_conj_expn)
    by blast .



definition "Union_the_Same_Or_Arbitrary_when_Var Z X Y  (v. (Z::'v  'a BI) v = X v + Y v)"

lemma Union_the_Same_Or_Arbitrary_when_Var__the_Same:
  Union_the_Same_Or_Arbitrary_when_Var Z Z Z
  unfolding Union_the_Same_Or_Arbitrary_when_Var_def by simp

lemma Union_the_Same_Or_Arbitrary_when_Var__Arbitrary:
  Union_the_Same_Or_Arbitrary_when_Var (λv. X v + Y v) X Y
  unfolding Union_the_Same_Or_Arbitrary_when_Var_def by blast

φreasoner_ML Union_the_Same_Or_Arbitrary_when_Var 1200 (Union_the_Same_Or_Arbitrary_when_Var ?Z ?X ?Y) = fn (_, (ctxt,sequent)) =>
  let
    val constTrueprop $ (Const (const_nameUnion_the_Same_Or_Arbitrary_when_Var, _)
          $ Z $ _ $ _) = Thm.major_prem_of sequent
  in (ctxt,
        (if is_Var (Term.head_of (Envir.beta_eta_contract Z))
         then @{thm Union_the_Same_Or_Arbitrary_when_Var__Arbitrary}
         else @{thm Union_the_Same_Or_Arbitrary_when_Var__the_Same})
        RS sequent) |> Seq.single
  end

proc (nodef) try'':
  assumes F: 𝗉𝗋𝗈𝖼 f  X  YY  𝗍𝗁𝗋𝗈𝗐𝗌 E
  assumes G: (v. 𝗉𝗋𝗈𝖼 g v  E v  YY  𝗍𝗁𝗋𝗈𝗐𝗌 EE2 )
  input  X
    output YY
  throws EE2
   apply_rule "__op_try__"
    F
    G
   .

proc (nodef) try':
  assumes A: Union_the_Same_Or_Arbitrary_when_Var Z Y1 Y2
  assumes F: 𝗉𝗋𝗈𝖼 f  X  Y1  𝗍𝗁𝗋𝗈𝗐𝗌 E
  assumes G: v. 𝗉𝗋𝗈𝖼 g v  E v  Y2  𝗍𝗁𝗋𝗈𝗐𝗌 E2
  input  X
    output Z
  throws E2
   apply_rule "__op_try__" F G
    unfold A[unfolded Union_the_Same_Or_Arbitrary_when_Var_def, THEN spec, symmetric]
  .





end