Theory IDE_CP_Reasoning1

chapter โ€นReasoning Processes in IDE-CP - Part Iโ€บ

text โ€นThe part includes small process that can be built without infrastructure of
  IDE-CP, and declarations of other large process.โ€บ

theory IDE_CP_Reasoning1
  imports Spec_Framework Phi_BI.Phi_BI
  abbrevs "<subj-reasoning>" = "๐—Œ๐—Ž๐–ป๐—ƒ-๐—‹๐–พ๐–บ๐—Œ๐—ˆ๐—‡๐—‚๐—‡๐—€"
begin

section โ€นAnnotations Guiding the Reasoningโ€บ

subsection โ€นSmall Annotationsโ€บ

subsubsection โ€นMatchesโ€บ

definition Assertion_Matches :: โ€น'a BI โ‡’ 'a BI โ‡’ 'a BIโ€บ (infixl "<matches>" 18)
  where โ€น(S <matches> pattern) = Sโ€บ

text โ€นThe annotation marking on a target termโ€นY <matches> Aโ€บ in a ToA or a view shift
  restricts that the source have to first match pattern โ€นAโ€บ.โ€บ

lemma [ฯ†reason 2000]:
  โ€นMatches X A โŸน X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—๐—‚๐—๐— P โŸน X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ (Y <matches> A) ๐—๐—‚๐—๐— Pโ€บ
  unfolding Assertion_Matches_def .

lemma [ฯ†reason 2000]:
  โ€นMatches X A โŸน X ๐—Œ๐—๐—‚๐–ฟ๐—๐—Œ Y ๐—๐—‚๐—๐— P โŸน X ๐—Œ๐—๐—‚๐–ฟ๐—๐—Œ (Y <matches> A) ๐—๐—‚๐—๐— Pโ€บ
  unfolding Assertion_Matches_def .

subsubsection โ€นUseless Tagโ€บ

definition USELESS :: โ€นbool โ‡’ boolโ€บ where โ€นUSELESS x = xโ€บ

lemma [simp]: โ€นUSELESS Trueโ€บ unfolding USELESS_def ..

text โ€นSimplification plays an important role in the programming in IDE_CP.
  We use it to simplify the specification and evaluate the abstract state.

  It is powerful as a transformation preserving all information,
  but sometimes we expect the transformation is weaker and unequal by disposing
  some useless information that we do not need.
  For example, we want to rewrite termโ€นx โฆ‚ Tโ€บ to termโ€นy โฆ‚ Uโ€บ but the rewrite may be held
  only with an additional proposition termโ€นUselessโ€บ which is useless for us,
  \[ propโ€นx โฆ‚ T โ‰ก y โฆ‚ U ๐—Œ๐—Ž๐–ป๐—ƒ Uselessโ€บ \]
  In cases like this, we can wrap the useless proposition by tag โ€นโ€นUSELESSโ€บโ€บ,
  as propโ€นx โฆ‚ T โ‰ก y โฆ‚ U ๐—Œ๐—Ž๐–ป๐—ƒ USELESS Uselessโ€บ. The equality is still held because
  propโ€นUSELESS P โ‰ก Pโ€บ, but IDE-CP is configured to drop the propโ€นUselessโ€บ
  so the work space will not be polluted by helpless propositions.
โ€บ

subsubsection โ€นGenerated Rules during Reasoning or Programmingโ€บ

text โ€นAnnotate a rule generated during the programming, to differentiate from the normal
  contextual facts. The normal facts are stored in โ€นฯ†lemmataโ€บ while the generated rules
  are in โ€นฯ†generatedโ€บ (or maybe a better name like ฯ†generated_rules?)โ€บ


text โ€นTODO: update this

Note, the argument here means any ฯ†-Type in the pre-condition, not necessary argument value.

  If in a procedure or an implication rule or a view shift rule,
  there is an argument where the procedure or the rule retains its structure,
  this argument can be marked by termโ€นSMORPH argโ€บ.

  Recall when applying the procedure or the rule, the reasoner extracts termโ€นargโ€บ from the
    current ฯ†-BI specification termโ€นXโ€บ of the current sequent.
  This extraction may break termโ€นXโ€บ especially when the termโ€นargโ€บ to be extracted is
    scattered and embedded in multiple ฯ†-Types in termโ€นXโ€บ.
  For example, extract termโ€น(x1, y2) โฆ‚ (A1 * B2)โ€บ from
    termโ€น((x1, x2) โฆ‚ (A1 * A2)) * ((y1, (y2, y3)) โฆ‚ (B1 * (B2 * B3)))โ€บ.
  After the application, the following sequent will have broken structures because
    the original structure of termโ€นXโ€บ is destroyed in order to extract termโ€นargโ€บ.
  However, the structure of the new termโ€นarg'โ€บ may not changes.
  If so, by reversing the extraction, it is possible to recovery the original structure of termโ€นXโ€บ,
    only with changed value of the corresponding part of termโ€นargโ€บ in termโ€นXโ€บ.

  The system supports multiple arguments to be marked by termโ€นSMORPH argโ€บ.
  And the system applies the reverse morphism in the correct order.
  A requirement is,
  those structural-retained argument should locate at the end of the procedure's or the rule's
    argument list. Or else, because the reasoner does not record the extraction morphism of
    arguments not marked by termโ€นSMORPH argโ€บ, those arguments which occur after the
    structural-retained arguments change the ฯ†-BI specification by their extraction
    causing the recorded morphism of previous termโ€นSMORPH argโ€บ mismatch the current
    ฯ†-BI specification and so possibly not able to be applied any more.
โ€บ


subsubsection โ€นBeta-reduction Hint for ฯ†-Typeโ€บ

definition ฮฒ_Hint_for_ฯ† (binder "ฮปฮฒ " 10)
  where โ€นฮฒ_Hint_for_ฯ† f โ‰ก fโ€บ

text โ€นOccasionally, it can be convenient technically to use โ€นx โฆ‚ (ฮปa. S a)โ€บ that will be ฮฒ-reduced
      transparently to โ€นSโ€บ. The tag constโ€นฮฒ_Hint_for_ฯ†โ€บ allowing syntax โ€นx โฆ‚ (ฮปฮฒ a. S a)โ€บ hints
      the reasoner to ฮฒ-reduce the ฯ†-type term.โ€บ

lemma ฮฒ_Hint_for_ฯ†[simp]:
  โ€นx โฆ‚ (ฮปฮฒ y. S y) โ‰ก S xโ€บ
  unfolding ฮฒ_Hint_for_ฯ†_def ฯ†Type_def .

paragraph โ€นIdentity_Elementโ€บ

lemma [ฯ†reason %cutting]:
  โ€น Identity_ElementI (S x) P
โŸน Identity_ElementI (x โฆ‚ (ฮปฮฒ y. S y)) P โ€บ
  by simp

lemma [ฯ†reason %cutting]:
  โ€น Identity_ElementE (S x)
โŸน Identity_ElementE (x โฆ‚ (ฮปฮฒ y. S y)) โ€บ
  by simp

paragraph โ€นTransformation Rulesโ€บ

lemma [ฯ†reason 1000]:
  โ€น S x ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—๐—‚๐—๐— P
โŸน x โฆ‚ (ฮปฮฒ y. S y) ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—๐—‚๐—๐— P โ€บ
  by simp

(*TODO! this ๐’œ?!*)
lemma [ฯ†reason 1000]:
  โ€น S x ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—๐—‚๐—๐— P @tag ๐’œ
โŸน x โฆ‚ (ฮปฮฒ y. S y) ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—๐—‚๐—๐— P @tag ๐’œ โ€บ
  by simp

lemma [ฯ†reason 1000]:
  โ€น S x * R ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—๐—‚๐—๐— P
โŸน (x โฆ‚ (ฮปฮฒ y. S y)) * R ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—๐—‚๐—๐— P โ€บ
  by simp

lemma [ฯ†reason 1000]:
  โ€น S x * R ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—๐—‚๐—๐— P @tag ๐’œ
โŸน (x โฆ‚ (ฮปฮฒ y. S y)) * R ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—๐—‚๐—๐— P @tag ๐’œ โ€บ
  by simp

lemma [ฯ†reason 1000]:
  โ€น X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ S x ๐—๐—‚๐—๐— P
โŸน X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ x โฆ‚ (ฮปฮฒ y. S y) ๐—๐—‚๐—๐— P โ€บ
  by simp

lemma [ฯ†reason 1000]:
  โ€น X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ S x ๐—๐—‚๐—๐— P @tag ๐’œ
โŸน X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ x โฆ‚ (ฮปฮฒ y. S y) ๐—๐—‚๐—๐— P @tag ๐’œ โ€บ
  by simp

lemma [ฯ†reason 1000]:
  โ€น X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ S x ๐—‹๐–พ๐—†๐–บ๐—‚๐—‡๐—Œ R ๐—๐—‚๐—๐— P
โŸน X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ x โฆ‚ (ฮปฮฒ y. S y) ๐—‹๐–พ๐—†๐–บ๐—‚๐—‡๐—Œ R ๐—๐—‚๐—๐— P โ€บ
  by simp

lemma [ฯ†reason 1000]:
  โ€น X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ S x ๐—‹๐–พ๐—†๐–บ๐—‚๐—‡๐—Œ R ๐—๐—‚๐—๐— P @tag ๐’œ
โŸน X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ x โฆ‚ (ฮปฮฒ y. S y) ๐—‹๐–พ๐—†๐–บ๐—‚๐—‡๐—Œ R ๐—๐—‚๐—๐— P @tag ๐’œ โ€บ
  by simp



section โ€นSmall Reasoning Processโ€บ

subsection โ€นAuxiliariesโ€บ


subsubsection โ€นSemantic Expansion of ฯ†-Typesโ€บ

consts MODE_ฯ†EXPN :: mode โ€• โ€นrelating to named_theorems โ€นฯ†expnโ€บโ€บ

abbreviation ฯ†expn_Premise ("<ฯ†expn> _" [26] 26) where โ€นฯ†expn_Premise โ‰ก Premise MODE_ฯ†EXPNโ€บ

ฯ†reasoner_ML ฯ†expn_Premise 10 (โ€น<ฯ†expn> ?Pโ€บ) = โ€น
  Seq.ORELSE (
  Phi_Reasoners.wrap (PLPR_Simplifier.simplifier (K Seq.empty) (fn ctxt =>
                            ctxt addsimps (Useful_Thms.get ctxt)) {fix_vars=false}),
  Phi_Reasoners.wrap (PLPR_Simplifier.simplifier (K Seq.empty) (fn ctxt =>
        Phi_Expansions.enhance (ctxt addsimps (Useful_Thms.get ctxt))) {fix_vars=false})) o snd
โ€บ

lemma Premise_MODE_ฯ†EXPN[iff]: โ€น<ฯ†expn> Trueโ€บ
  unfolding Premise_def ..

text โ€นAntecedent propโ€น<ฯ†expn> Pโ€บ indicates the reasoner solving the premise propโ€นPโ€บ using
  simplification rules of โ€นฯ†expnsโ€บ.โ€บ

subsubsection โ€นName tag by typeโ€บ

(*TODO: elaborate this*)

datatype ('x, 'name) named (infix "<named>" 30) = tag 'x (*TODO: rename!!*)

syntax "__named__" :: โ€นlogic โ‡’ tuple_args โ‡’ logicโ€บ (infix "<<named>>" 25)


ML_file โ€นlibrary/syntax/name_by_type.MLโ€บ

text โ€นIt is a tool to annotate names on a term, e.g. termโ€นx <<named>> a, bโ€บ.
  The name tag is useful in lambda abstraction (including quantification) because the
  name of an abstraction variable is not preserved in many transformation especially
  simplifications. The name can be useful in the deductive programming, e.g. universally
  quantified variables in a sub-procedure like
  \[ โ€นโˆ€x y. proc f โฆƒ VAL x โฆ‚ TโŸ VAL y โฆ‚ U โŸผ any โฆ„ โŸน any'โ€บ \]
  When starting to write the sub-procedure f by command โ€นโดโ€บ, ฯ†-system fixes variables x and y
    with the name of x and y. The name of x and y then are significant for programming.
  To preserve the name, we use typโ€น'any <named> 'ฯ†name_x ร— 'ฯ†name_yโ€บ,
    propโ€นโˆ€(x :: 'any <named> 'ฯ†name_x). sthโ€บ.
  We use free type variable to annotate it because it is most stable. No transformation
    changes the name of a free type variable.

  This feature is mostly used in โˆ—โ€นExpansion of Quantificationโ€บ given in the immediate subsection.
  Therefore we put this part in the subsection of reasoning jobs, though itself is not related to
  any reasoning work.
โ€บ

lemma named_forall: "All P โŸท (โˆ€x. P (tag x))" by (metis named.exhaust)
lemma named_exists: "Ex P โŸท (โˆƒx. P (tag x))" by (metis named.exhaust)
lemma [simp]: "tag (case x of tag x โ‡’ x) = x" by (cases x) simp
lemma named_All: "(โ‹€x. PROP P x) โ‰ก (โ‹€x. PROP P (tag x))"
proof fix x assume "(โ‹€x. PROP P x)" then show "PROP P (tag x)" .
next fix x :: "'a <named> 'b" assume "(โ‹€x. PROP P (tag x))" from โ€นPROP P (tag (case x of tag x โ‡’ x))โ€บ show "PROP P x" by simp
qed

lemma named_ExBI: "(โˆƒ*c. T c) = (โˆƒ*c. T (tag c) )" by (clarsimp simp add: named_exists BI_eq_iff)


subsubsection โ€นExpansion of Quantificationโ€บ

definition โ€นeoq__fst = fstโ€บ
definition โ€นeoq__snd = sndโ€บ

named_theorems named_expansion โ€นRewriting rules expanding named quantification.โ€บ

lemma eoq__fst[unfolded atomize_eq[symmetric], named_expansion]:
        โ€นeoq__fst (x,y) = xโ€บ unfolding eoq__fst_def by simp
lemma eoq__snd[unfolded atomize_eq[symmetric], named_expansion]:
        โ€นeoq__snd (x,y) = yโ€บ unfolding eoq__snd_def by simp

lemmas [unfolded atomize_eq[symmetric], named_expansion] =
  Product_Type.prod.case named.case id_apply

ML_file  "./library/tools/quant_expansion.ML"

hide_fact  eoq__fst eoq__snd
hide_const eoq__fst eoq__snd

simproc_setup named_forall_expansion ("All (P :: 'a <named> 'names โ‡’ bool)") =
  โ€นK (QuantExpansion.simproc_of
          (fn Type(type_nameโ€นฯ†argโ€บ, _) => QuantExpansion.forall_expansion_arg_encoding
            | _ => QuantExpansion.forall_expansion))โ€บ

simproc_setup named_ex_expansion ("Ex (P :: 'a <named> 'names โ‡’ bool)") =
  โ€นK (QuantExpansion.simproc_of
          (fn Type(type_nameโ€นฯ†argโ€บ, _) => QuantExpansion.exists_expansion_arg_encoding
            | _ => QuantExpansion.exists_expansion))โ€บ

simproc_setup named_exSet_expansion ("ExBI (P :: 'a <named> 'names โ‡’ 'b BI)") =
  โ€นK (QuantExpansion.simproc_of (K QuantExpansion.ExNu_expansion))โ€บ

simproc_setup named_metaAll_expansion ("Pure.all (P :: 'a <named> 'names โ‡’ prop)") =
  โ€นK (QuantExpansion.simproc_of
          (fn Type(type_nameโ€นฯ†argโ€บ, _) => QuantExpansion.meta_All_expansion_arg_encoding
            | _ => QuantExpansion.meta_All_expansion))โ€บ

(*TODO: merge to procedure 1*)
ML_file "./library/syntax/procedure3.ML"


subsubsection โ€นRename ฮป-Abstractionโ€บ

definition rename_abstraction :: โ€น'ฯ†name_name itself โ‡’ 'a โ‡’ 'a โ‡’ boolโ€บ
  where โ€นrename_abstraction name origin_abs named_abs โŸท (origin_abs = named_abs)โ€บ

lemma rename_abstraction:
  โ€นrename_abstraction name X Xโ€บ
  unfolding rename_abstraction_def ..

ฯ†reasoner_ML rename_abstraction 1100 (โ€นrename_abstraction TYPE(?'name) ?Y ?Y'โ€บ) =
โ€นfn (_, (ctxt, sequent)) =>
  case Thm.major_prem_of sequent
    of constโ€นTruepropโ€บ $ (Const (const_nameโ€นrename_abstractionโ€บ, _)
                $ (Const (const_nameโ€นPure.typeโ€บ, Type(type_nameโ€นitselfโ€บ, [name'])))
                $ Abs(_,ty,body)
                $ Var Y'') =>
      let
        val name = case Phi_Syntax.dest_name_tylabels name'
                     of [x] => x
                      | _ => raise TYPE ("only one name is expected", [name'], [])
        val Y' = Abs(name, ty, body) |> Thm.cterm_of ctxt
        val sequent = @{thm rename_abstraction} RS Thm.instantiate (TVars.empty, Vars.make [(Y'',Y')]) sequent
      in
        Seq.single (ctxt, sequent)
      end
     | term => raise THM ("Bad shape of rename_abstraction antecedent", 0, [sequent])
โ€บ

hide_fact rename_abstraction


subsubsection โ€นฮป-Abstraction Tagโ€บ

definition "lambda_abstraction" :: " 'a โ‡’ 'b โ‡’ ('a โ‡’ 'b) โ‡’ bool "
  where "lambda_abstraction x Y Y' โŸท Y' x = Y"

lemma lambda_abstraction: "lambda_abstraction x (Y' x) Y'"
  unfolding lambda_abstraction_def ..

lemma [ฯ†reason 1200 for โ€นlambda_abstraction (?x,?y) ?fx ?fโ€บ]:
  โ€น lambda_abstraction y fx f1
โŸน lambda_abstraction x f1 f2
โŸน lambda_abstraction (x,y) fx (case_prod f2)โ€บ
  unfolding lambda_abstraction_def by simp

ฯ†reasoner_ML lambda_abstraction 1100 ("lambda_abstraction ?x ?Y ?Y'") = โ€นfn (_, (ctxt, sequent)) =>
  let
    val (Vs, _, constโ€นTruepropโ€บ $ (Const (const_nameโ€นlambda_abstractionโ€บ, _) $ x $ Y $ _))
      = Phi_Help.leading_antecedent (Thm.prop_of sequent)
    val Y' = Abs("", fastype_of x, abstract_over (x, Y))
    val idx = Thm.maxidx_of sequent + 1
    val vars = map Var (List.tabulate (length Vs, (fn i => ("v", i+idx))) ~~ map snd Vs)
    fun subst X = Term.subst_bounds (vars, X)
    val idx = idx + length Vs
    val rule = Drule.infer_instantiate ctxt
                  (map (apsnd (Thm.cterm_of ctxt)) [(("x",idx), subst x), (("Y'",idx),subst Y')])
                  (Thm.incr_indexes idx @{thm lambda_abstraction})
  in
    Seq.single (ctxt, rule RS sequent)
  end
โ€บ

hide_fact lambda_abstraction

lemma [ฯ†reason 1200 for โ€นlambda_abstraction (tag ?x) ?fx ?fโ€บ]:
  โ€น lambda_abstraction x fx f
โŸน rename_abstraction TYPE('name) f f'
โŸน lambda_abstraction (tag x :: 'any <named> 'name) fx (case_named f')โ€บ
  unfolding lambda_abstraction_def rename_abstraction_def by simp


subsubsection โ€นIntroduce Frame Variableโ€บ

named_theorems frame_var_rewrs โ€นRewriting rules to normalize after inserting the frame variableโ€บ

declare mult.assoc[symmetric, frame_var_rewrs]
  Subjection_times[frame_var_rewrs]
  ExBI_times_right[frame_var_rewrs]

consts frame_var_rewrs :: mode

ฯ†reasoner_ML Subty_Simplify 2000 (โ€นSimplify frame_var_rewrs ?x ?yโ€บ)
  = โ€นPhi_Reasoners.wrap (PLPR_Simplifier.simplifier_only (K Seq.empty) (fn ctxt =>
          Named_Theorems.get ctxt named_theoremsโ€นframe_var_rewrsโ€บ) {fix_vars=false}) o sndโ€บ

definition ฯ†IntroFrameVar :: "'a::sep_magma BI option โ‡’ 'a BI โ‡’ 'a BI โ‡’ 'a BI โ‡’ 'a BI โ‡’ bool"
  where "ฯ†IntroFrameVar R S' S T' T โŸท (case R of Some R' โ‡’ S' = (S * R') โˆง T' = T * R'
                                                 | None โ‡’ S' = S โˆง T' = T )"

definition ฯ†IntroFrameVar' ::
  "assn โ‡’ assn โ‡’ assn โ‡’ ('ret โ‡’ assn) โ‡’ ('ret โ‡’ assn) โ‡’ ('ex โ‡’ assn) โ‡’ ('ex โ‡’ assn) โ‡’ bool"
  where "ฯ†IntroFrameVar' R S' S T' T E' E โŸท S' = (S * R) โˆง T' = (ฮปret. T ret * R) โˆง E' = (ฮปex. E ex * R) "

definition TAIL :: โ€นassn โ‡’ assnโ€บ where โ€นTAIL S = Sโ€บ

text โ€นAntecedent schematic_propโ€นฯ†IntroFrameVar ?R ?S' S ?T' Tโ€บ appends a frame variable
  schematic_termโ€น?Rโ€บ to the source MTF termโ€นSโ€บ if the items in termโ€นSโ€บ do not have an ending
  frame variable already nor the ending item is not tagged by โ€นTAILโ€บ.
  If so, the reasoner returns โ€น?S' := S * ?Rโ€บ for a schematic โ€น?Rโ€บ,
  or else, the โ€นSโ€บ is returned unchanged โ€น?S' := ?Sโ€บ.
  โ€นฯ†IntroFrameVar'โ€บ is similar.

  Tag โ€นTAILโ€บ is meaningful only when it tags the last item of a โ€นโˆ—โ€บ-sequence.
  It has a meaning of `the remaining everything' like, the target (RHS) item tagged by this
  means the item matches the whole remaining part of the source (LHS) part.
  โ€นTAILโ€บ also means, the tagged item is at the end and has a sense of ending, so no further
  padding is required (e.g. padding-of-void during NToA reasoning).
โ€บ

lemma ฯ†IntroFrameVar_No:
  "ฯ†IntroFrameVar None S S T T"
  unfolding ฯ†IntroFrameVar_def by simp

lemma ฯ†IntroFrameVar'_No:
  "ฯ†IntroFrameVar' 1 S S T T E E"
  unfolding ฯ†IntroFrameVar'_def by simp

lemma ฯ†IntroFrameVar_Yes:
  "ฯ†IntroFrameVar (Some R) (S ๐—‹๐–พ๐—†๐–บ๐—‚๐—‡๐—Œ R) S (T ๐—‹๐–พ๐—†๐–บ๐—‚๐—‡๐—Œ R) T"
  unfolding ฯ†IntroFrameVar_def REMAINS_def by simp

lemma ฯ†IntroFrameVar'_Yes:
  " ฯ†IntroFrameVar' R (S ๐—‹๐–พ๐—†๐–บ๐—‚๐—‡๐—Œ R) S (ฮปret. T ret * R) T (ฮปex. E ex * R) E"
  unfolding ฯ†IntroFrameVar'_def REMAINS_def by simp

ฯ†reasoner_ML ฯ†IntroFrameVar 1000 ("ฯ†IntroFrameVar ?R ?S' ?S ?T' ?T") =
โ€นfn (_, (ctxt, sequent)) =>
  let val (Const (const_nameโ€นฯ†IntroFrameVarโ€บ, Typeโ€นfun Typeโ€นoption TYโ€บ _โ€บ) $ _ $ _ $ S $ _ $ _) =
          Thm.major_prem_of sequent |> HOLogic.dest_Trueprop
      val suppressed = not (Sign.of_sort (Proof_Context.theory_of ctxt) (TY, sortโ€นsep_magma_1โ€บ))
                orelse case S
                         of Const(const_nameโ€นREMAINSโ€บ, _) $ _ $ R =>
                              Term.is_Var (Term.head_of R)
                          | _ => (case Phi_Syntax.rightmost_sep S
                         of (constโ€นTAILโ€บ $ _) => true
                          | RR => Term.is_Var (Term.head_of RR))
  in if suppressed
     then Seq.single (ctxt, @{thm ฯ†IntroFrameVar_No}  RS sequent)
     else Seq.single (ctxt, @{thm ฯ†IntroFrameVar_Yes} RS sequent)
  endโ€บ

ฯ†reasoner_ML ฯ†IntroFrameVar' 1000 ("ฯ†IntroFrameVar' ?R ?S' ?S ?T' ?T ?E' ?E") =
โ€นfn (_, (ctxt, sequent)) =>
  let val (Const (const_nameโ€นฯ†IntroFrameVar'โ€บ, _) $ _ $ _ $ S $ _ $ _ $ _ $ _) =
          Thm.major_prem_of sequent |> HOLogic.dest_Trueprop
      val suppressed = case S
                         of Const(const_nameโ€นREMAINSโ€บ, _) $ _ $ R =>
                              Term.is_Var (Term.head_of R)
                          | _ => (case Phi_Syntax.rightmost_sep S
                         of (constโ€นTAILโ€บ $ _) => true
                          | RR => Term.is_Var (Term.head_of RR))
  in if suppressed
     then Seq.single (ctxt, @{thm ฯ†IntroFrameVar'_No}  RS sequent)
     else Seq.single (ctxt, @{thm ฯ†IntroFrameVar'_Yes} RS sequent)
  endโ€บ

hide_fact ฯ†IntroFrameVar_No ฯ†IntroFrameVar'_No ฯ†IntroFrameVar_Yes ฯ†IntroFrameVar'_Yes


subsubsection โ€นReasoning Goals Embedded in BI Assertionโ€บ

definition Subj_Reasoning :: โ€น 'p BI โ‡’ bool โ‡’ 'p BI โ€บ (infixl "๐—Œ๐—Ž๐–ป๐—ƒ-๐—‹๐–พ๐–บ๐—Œ๐—ˆ๐—‡๐—‚๐—‡๐—€" 15)
  where โ€นSubj_Reasoning โ‰ก Subjectionโ€บ

lemma [ฯ†reason 1000]:
  โ€น X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—๐—‚๐—๐— P
โŸน A
โŸน X ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Y ๐—Œ๐—Ž๐–ป๐—ƒ-๐—‹๐–พ๐–บ๐—Œ๐—ˆ๐—‡๐—‚๐—‡๐—€ A ๐—๐—‚๐—๐— Pโ€บ
  unfolding Subj_Reasoning_def Transformation_def
  by simp

subsection โ€นEmbed BI Assertion into ฯ†-Typeโ€บ

lemma ฯ†Type_conv_eq_1:
  โ€นT = U โŸน (x โฆ‚ T) = U xโ€บ
  unfolding ฯ†Type_def by simp

lemma ฯ†Type_conv_eq_2:
  โ€นT = U โŸน (x โฆ‚ T) = (x โฆ‚ U)โ€บ
  unfolding ฯ†Type_def by simp

ML_file โ€นlibrary/phi_type_algebra/helps.MLโ€บ
ML_file โ€นlibrary/tools/embed_BI_into_phi_types.MLโ€บ

consts mode_embed_into_ฯ†type :: mode

ฯ†reasoner_ML Simp_Premise 10 (โ€น๐—Œ๐—‚๐—†๐—‰๐—…๐—‚๐–ฟ๐—’[mode_embed_into_ฯ†type] _ : _โ€บ)
  = โ€นPhi_Reasoners.wrap (PLPR_Simplifier.simplifier (K Seq.empty)
                        (fn ctxt => Embed_into_Phi_Type.equip ctxt) {fix_vars=true}) o sndโ€บ

 
lemmas [embed_into_ฯ†type] =
    ฯ†None_itself_is_one[where any=โ€น()โ€บ] ฯ†Prod_expn' ฯ†Any_def

ML โ€นEmbed_into_Phi_Type.print context trueโ€บ

paragraph โ€นDebug Usageโ€บ

method_setup embed_into_ฯ†type = โ€น
let val no_asmN = "no_asm";
    val no_asm_useN = "no_asm_use";
    val no_asm_simpN = "no_asm_simp";
    val asm_lrN = "asm_lr";

    fun conv_mode x =
      ((Args.parens (Args.$$$ no_asmN) >> K simp_tac ||
        Args.parens (Args.$$$ no_asm_simpN) >> K asm_simp_tac ||
        Args.parens (Args.$$$ no_asm_useN) >> K full_simp_tac ||
        Scan.succeed asm_full_simp_tac) |> Scan.lift) x;
in conv_mode >> (fn simp => fn ctxt =>
      Method.METHOD (fn ths => Method.insert_tac ctxt ths 1 THEN simp
          (Phi_Conv.Embed_into_Phi_Type.equip ctxt) 1 ))
endโ€บ


subsection โ€นSemantic Type of Multiple Valuesโ€บ

lemma [ฯ†reason 1200 for โ€นSemantic_Types_i (ฮปvs. ?x โฆ‚ ๐—๐–บ๐—…[ฯ†V_fst vs] ?TโŸ ?R vs) _โ€บ]:
  โ€น Semantic_Type T TY
โŸน Semantic_Types_i (ฮปvs. R vs) TYs
โŸน Semantic_Types_i (ฮปvs. x โฆ‚ ๐—๐–บ๐—…[ฯ†V_fst vs] TโŸ R (ฯ†V_snd vs)) (TY#TYs)โ€บ
  unfolding Semantic_Types_i_def Semantic_Types_def
            Well_Typed_Vals_def ฯ†arg_forall Semantic_Type_def subset_iff
  by (clarsimp simp add: to_vals_prod_def to_vals_VAL_def Val_inh_rewr)

lemma [ฯ†reason 1200]:
  โ€น Semantic_Type T TY
โŸน Semantic_Types_i (ฮปvs. x โฆ‚ ๐—๐–บ๐—…[vs] TโŸ R) [TY]โ€บ
  unfolding Semantic_Types_i_def Semantic_Types_def
            Well_Typed_Vals_def ฯ†arg_forall Semantic_Type_def subset_iff
  by (clarsimp simp add: to_vals_prod_def to_vals_VAL_def Val_inh_rewr)

lemma [ฯ†reason 1200]:
  โ€น Semantic_Types_i R TYs
โŸน Semantic_Types_i (ฮปvs. SโŸ R vs) TYsโ€บ
  unfolding Semantic_Types_i_def Semantic_Types_def Well_Typed_Vals_def by clarsimp

lemma [ฯ†reason 2000]:
  โ€น Semantic_Types_i (ฮป_::unit ฯ†arg. Void) []โ€บ
  unfolding Semantic_Types_i_def Semantic_Types_def Well_Typed_Vals_def to_vals_unit_def by clarsimp

lemma [ฯ†reason 1020 except โ€นSemantic_Types_i (ฮปvs. ?A vsโŸ ?B vs) _โ€บ]:
  โ€น Semantic_Types_i (ฮปvs. R vsโŸ Void) TYs
โŸน Semantic_Types_i R TYsโ€บ
  unfolding Semantic_Types_i_def Well_Typed_Vals_def by clarsimp

lemma [ฯ†reason 1000]:
  โ€น FAIL TEXT(โ€นFail to infer the semantic type ofโ€บ R)
โŸน Semantic_Types_i R TYsโ€บ
  unfolding Semantic_Types_i_def Well_Typed_Vals_def FAIL_def by clarsimp

lemma [ฯ†reason 1200]:
  โ€น Semantic_Types_i (ฮปret. (exp ret) (v ret)) TYs
โŸน Semantic_Types_i (ฮปret. Let (v ret) (exp ret)) TYsโ€บ
  unfolding Let_def .

lemma [ฯ†reason 1200]:
  โ€น Semantic_Types_i (ฮปret. f ret (fst (x ret)) (snd (x ret))) TYs
โŸน Semantic_Types_i (ฮปret. case_prod (f ret) (x ret)) TYsโ€บ
  by (simp add: case_prod_beta')

lemma [ฯ†reason 1200]:
  โ€น(โ‹€x. Semantic_Types_i (ฮปret. (S ret) x) TYs)
โŸน Semantic_Types_i (ฮปret. ExBI (S ret)) TYsโ€บ
  unfolding Semantic_Types_i_def Semantic_Types_def Well_Typed_Vals_def Satisfiable_def ExBI_expn
  by clarsimp blast

lemma [ฯ†reason 1200]:
  โ€น(โ‹€x. Semantic_Types_i (ฮปret. S ret) TYs)
โŸน Semantic_Types_i (ฮปret. S ret ๐—Œ๐—Ž๐–ป๐—ƒ P ret) TYsโ€บ
  unfolding Semantic_Types_i_def Semantic_Types_def Well_Typed_Vals_def Satisfiable_def Subjection_expn
  by clarsimp


subsection โ€นRemoving Valuesโ€บ (*TODO: depreciate me*)

definition โ€นRemove_Values (Input::assn) (Output::assn) โŸท (Input ๐—๐—‹๐–บ๐—‡๐—Œ๐–ฟ๐—ˆ๐—‹๐—†๐—Œ Output)โ€บ

text โ€นThe process propโ€นRemove_Values Input Outputโ€บ removes value assertions โ€นx โฆ‚ ๐—๐–บ๐—… Tโ€บ
  from the assertion โ€นInputโ€บ. Bounded values such the return value of a procedure are not removed.โ€บ

text โ€นGiven an assertion X, antecedent termโ€นRemove_Values X X'โ€บ
  returns X' where all free value assertions termโ€นx โฆ‚ Val raw Tโ€บ filtered out, where termโ€นrawโ€บ
  contains at least one free variable of typโ€น'a ฯ†argโ€บ.

  It is typically used in exception. When a computation triggers an exception at state X,
    the state recorded in the exception is exactly X' where value assertions are filtered out.โ€บ

declare [[ฯ†reason_default_pattern โ€นRemove_Values ?X _โ€บ โ‡’ โ€นRemove_Values ?X _โ€บ (100)]]

(* lemma [ฯ†reason for โ€นRemove_Values ?ex ?var_X ?Zโ€บ]:
  โ€นRemove_Values ex X Xโ€บ
  unfolding Remove_Values_def using transformation_refl . *)

lemma [ฯ†reason 1200]:
  โ€น(โ‹€c. Remove_Values (T c) (T' c))
โŸน Remove_Values (ExBI T) (ExBI T')โ€บ
  unfolding Remove_Values_def Transformation_def
  by simp blast

lemma [ฯ†reason 1200]:
  โ€น(โ‹€c. Remove_Values (T c * R) (T' c * R'))
โŸน Remove_Values (ExBI T * R) (ExBI T' * R')โ€บ
  unfolding Remove_Values_def Transformation_def
  by simp blast

lemma [ฯ†reason 1200]:
  โ€น Remove_Values T T'
โŸน Remove_Values (T ๐—Œ๐—Ž๐–ป๐—ƒ P) (T' ๐—Œ๐—Ž๐–ป๐—ƒ P)โ€บ
  unfolding Remove_Values_def Transformation_def
  by simp

lemma [ฯ†reason 1200]:
  โ€น Remove_Values (T * R) (T' * R')
โŸน Remove_Values ((T ๐—Œ๐—Ž๐–ป๐—ƒ P) * R) ((T' ๐—Œ๐—Ž๐–ป๐—ƒ P) * R')โ€บ
  unfolding Remove_Values_def Transformation_def
  by simp

lemma [ฯ†reason 1200]:
  โ€น Remove_Values A A'
โŸน Remove_Values B B'
โŸน Remove_Values (A ๐—‹๐–พ๐—†๐–บ๐—‚๐—‡๐—Œ B) (A' ๐—‹๐–พ๐—†๐–บ๐—‚๐—‡๐—Œ B')โ€บ
  unfolding REMAINS_def Remove_Values_def Transformation_def REMAINS_def
  by (simp; blast)

lemma [ฯ†reason 1200]:
  โ€น Remove_Values A A'
โŸน Remove_Values B B'
โŸน Remove_Values (A + B) (A' + B')โ€บ
  unfolding Remove_Values_def Transformation_def
  by blast

lemma [ฯ†reason 1200]:
  โ€น Remove_Values R R'
โŸน Remove_Values ((x โฆ‚ Val raw T) * R) R'โ€บ
  unfolding Remove_Values_def Transformation_def by (simp add: Val_expn)

lemma [ฯ†reason 1200]:
  โ€นRemove_Values (x โฆ‚ Val raw T) 1โ€บ
  unfolding Remove_Values_def Transformation_def by (simp add: Val_expn)

lemma [ฯ†reason 1200]:
  โ€น Remove_Values A A'
โŸน Remove_Values (1 * A) A'โ€บ
  unfolding Remove_Values_def Transformation_def by simp

lemma [ฯ†reason 1200]:
  โ€น Remove_Values A A'
โŸน Remove_Values (A * 1) A'โ€บ
  unfolding Remove_Values_def Transformation_def by simp

lemma [ฯ†reason 1200]:
  โ€นRemove_Values (0 * A) 0โ€บ
  unfolding Remove_Values_def Transformation_def by simp

lemma [ฯ†reason 1100]:
  โ€น Remove_Values A A'
โŸน Remove_Values B B'
โŸน Remove_Values (A * B) (A' * B')โ€บ
  unfolding Remove_Values_def Transformation_def by simp blast

lemma [ฯ†reason 1000]:
  โ€น Remove_Values A Aโ€บ
  unfolding Remove_Values_def
  by simp



section โ€นDeclaration of Reasonig Processโ€บ

subsection โ€นDeclaration of Convergence of Branchโ€บ

consts invoke_br_join :: โ€นactionโ€บ (*TODO: move?*)


end