src/Tools/isac/BridgeJEdit/Calculation.thy
author Walther Neuper <walther.neuper@jku.at>
Wed, 09 Dec 2020 16:24:26 +0100
changeset 60127 3c9f1835aff3
parent 60126 d41d42eada78
child 60128 194abef60d3b
permissions -rw-r--r--
tuned
     1 (*  Title:      src/Tools/isac/BridgeJEdit/Calculation.thy
     2     Author:     Walther Neuper, JKU Linz
     3     (c) due to copyright terms
     4 
     5 Outer syntax for Isabelle/Isac's Calculation.
     6 *)
     7 
     8 theory Calculation
     9 imports
    10   "~~/src/Tools/isac/MathEngine/MathEngine"
    11 (**)"HOL-SPARK.SPARK" (** ) preliminarily for parsing Example files *)
    12 (** )"HOL-Word.Word"( ** ) trial on ERROR in definition sdiv below *)
    13 keywords
    14     "Example" :: thy_load ("str") (* "spark_vc" :: thy_goal *)
    15   and "Problem" :: thy_goal (* root-problem + recursively in Solution *)
    16   and "Specification" "Model" "References" "Solution" (* structure only *)
    17   and"Given" "Find" "Relate" "Where" (* await input of term *)
    18   and "RTheory" (* await input of string; "R" distingues "Problem".."RProblem" *)
    19   and "RProblem" "RMethod" (* await input of string list *)
    20     "Tactic" (* optional for each step 0..end of calculation *)
    21 (*//-------------------- investigate Outer_Syntax.local_theory_to_proof -------------------\\*)
    22   and"global_interpretationC" :: thy_goal
    23 (*\\-------------------- investigate Outer_Syntax.local_theory_to_proof -------------------//*)
    24 begin
    25 
    26 (**)ML_file parseC.sml(**)
    27 
    28 section \<open>new code for Outer_Syntax Example, Problem, ...\<close>
    29 
    30 subsection \<open>code for Example\<close>
    31 ML \<open>
    32 \<close> ML \<open>
    33 structure Refs_Data = Theory_Data
    34 (
    35   type T = References.T
    36   val empty : T = References.empty
    37   val extend = I
    38   fun merge (_, refs) = refs
    39 );
    40 (*/----------------------------- shift to test/../? ----------------------------------------\*)
    41 (* Pure/context.ML
    42 signature THEORY_DATA =
    43 sig
    44   type T
    45   val get: theory -> T
    46   val put: T -> theory -> theory
    47   val map: (T -> T) -> theory -> theory
    48 end;*)
    49 (*
    50 Refs_Data.empty;                                    (*in Refs_Data defined workers are hidden*)
    51 Refs_Data.extend;                                   (*in Refs_Data defined workers are hidden*)
    52 Refs_Data.merge;                                    (*in Refs_Data defined workers are hidden*)
    53 ML error\<^here>:
    54 Value or constructor (empty) has not been declared in structure Refs *)
    55 
    56 Refs_Data.get: theory -> Refs_Data.T;                            (*from signature THEORY_DATA*)
    57 Refs_Data.put: Refs_Data.T -> theory -> theory;                  (*from signature THEORY_DATA*)
    58 Refs_Data.map: (Refs_Data.T -> Refs_Data.T) -> theory -> theory; (*from signature THEORY_DATA*)
    59 (*\----------------------------- shift to test/../? ----------------------------------------/*)
    60 \<close> ML \<open>
    61 structure OMod_Data = Theory_Data
    62 (
    63   type T = O_Model.T
    64   val empty : T = []
    65   val extend = I
    66   fun merge (_, o_model) = o_model
    67 )
    68 \<close> ML \<open>
    69 structure Ctxt_Data = Theory_Data
    70 (
    71   type T = Proof.context
    72   val empty : T = ContextC.empty
    73   val extend = I
    74   fun merge (_, ctxt) = ctxt
    75 )
    76 \<close> ML \<open>
    77 fun store_and_show formalise thy =
    78   let
    79 (**)val file_read_correct = case formalise of xxx as
    80       [(["Traegerlaenge L", "Streckenlast q_0", "Biegelinie y", "Randbedingungen [y 0 = (0::real), y L = 0, M_b 0 = 0, M_b L = 0]", "FunktionsVariable x", "GleichungsVariablen [c, c_2, c_3, c_4]", "AbleitungBiegelinie dy"],
    81         ("Biegelinie", ["Biegelinien"], ["IntegrierenUndKonstanteBestimmen2"]))] => hd xxx
    82       | _ => error "magic failed: handling file exp_Statics_Biegel_Timischl_7-70.str failed"
    83 (**)
    84     val formalise = hd formalise (*we expect only one Formalise.T in the list*)
    85     val (hdlPIDE, _, refs, o_model, var_type_ctxt) = Step_Specify.initialisePIDE formalise
    86   (*              ^^ TODO remove with cleanup in nxt_specify_init_calc *)
    87 (*
    88   TODO: present "Problem hdlPIDE" via PIDE
    89 *)
    90   in
    91     thy
    92       |> Refs_Data.put refs
    93       |> OMod_Data.put o_model
    94       |> Ctxt_Data.put var_type_ctxt
    95   end;
    96 \<close> ML \<open>
    97 fun load_formalisation parser (files, _) thy =
    98   let
    99     val ([{lines, pos, ...}: Token.file], thy') = files thy;
   100   in
   101     store_and_show
   102       (ParseC.read_out_formalise (fst (parser (fst (ParseC.scan' pos (cat_lines lines))))))
   103         thy'
   104   end;
   105 \<close> ML \<open>
   106 \<close>
   107 
   108 subsection \<open>code to write Problem ("Biegelinie", ["Biegelinien"]) to thy\<close>
   109 ML \<open>
   110 \<close> ML \<open>
   111 \<close> ML \<open>
   112 \<close> ML \<open>
   113 \<close>
   114 
   115 subsection \<open>code for Problem\<close>
   116 text \<open>
   117   Again, we copy code from spark_vc into Calculation.thy and
   118   add functionality for Problem
   119   such that the code keeps running during adaption from spark_vc to Problem.
   120 \<close> ML \<open>
   121 \<close> ML \<open>
   122 \<close> 
   123 
   124 subsubsection \<open>copied from fdl_parser.ML\<close>
   125 ML \<open>
   126 \<close> ML \<open>
   127 datatype expr =
   128     Ident of string
   129   | Number of int
   130   | Quantifier of string * string list * string * expr
   131   | Funct of string * expr list
   132   | Element of expr * expr list
   133   | Update of expr * expr list * expr
   134   | Record of string * (string * expr) list
   135   | Array of string * expr option *
   136       ((expr * expr option) list list * expr) list;
   137 \<close> ML \<open>
   138   datatype fdl_type =
   139       Basic_Type of string
   140     | Enum_Type of string list
   141     | Array_Type of string list * string
   142     | Record_Type of (string list * string) list
   143     | Pending_Type;
   144 \<close> ML \<open>
   145 (* also store items in a list to preserve order *)
   146 type 'a tab = 'a Symtab.table * (string * 'a) list;
   147 \<close> ML \<open>
   148 fun lookup ((tab, _) : 'a tab) = Symtab.lookup tab;
   149 \<close> ML \<open>
   150 \<close>
   151 subsubsection \<open>copied from spark_vcs.ML\<close>
   152 ML \<open>
   153 \<close> ML \<open>
   154 fun err_unfinished () = error "An unfinished SPARK environment is still open."
   155 \<close> ML \<open>
   156 val strip_number = apply2 implode o chop_suffix Fdl_Lexer.is_digit o raw_explode;
   157 \<close> ML \<open>
   158 val name_ord = prod_ord string_ord (option_ord int_ord) o
   159   apply2 (strip_number ##> Int.fromString);
   160 \<close> ML \<open>
   161 structure VCtab = Table(type key = string val ord = name_ord);
   162 \<close> ML \<open>
   163 val builtin = Symtab.make (map (rpair ())
   164   ["->", "<->", "or", "and", "not", "=", "<>", "<", ">", "<=", ">=",
   165    "+", "-", "*", "/", "div", "mod", "**"]);
   166 \<close> ML \<open>
   167 val is_pfun =
   168   Symtab.defined builtin orf
   169   can (unprefix "fld_") orf can (unprefix "upf_") orf
   170   can (unsuffix "__pos") orf can (unsuffix "__val") orf
   171   equal "succ" orf equal "pred";
   172 \<close> ML \<open>
   173 fun fold_opt f = the_default I o Option.map f;
   174 fun fold_pair f g (x, y) = f x #> g y;
   175 \<close> ML \<open>
   176 fun fold_expr f g (Funct (s, es)) = f s #> fold (fold_expr f g) es
   177   | fold_expr f g (Ident s) = g s
   178   | fold_expr f g (Number _) = I
   179   | fold_expr f g (Quantifier (_, _, _, e)) = fold_expr f g e
   180   | fold_expr f g (Element (e, es)) =
   181       fold_expr f g e #> fold (fold_expr f g) es
   182   | fold_expr f g (Update (e, es, e')) =
   183       fold_expr f g e #> fold (fold_expr f g) es #> fold_expr f g e'
   184   | fold_expr f g (Record (_, flds)) = fold (fold_expr f g o snd) flds
   185   | fold_expr f g (Array (_, default, assocs)) =
   186       fold_opt (fold_expr f g) default #>
   187       fold (fold_pair
   188         (fold (fold (fold_pair
   189           (fold_expr f g) (fold_opt (fold_expr f g)))))
   190         (fold_expr f g)) assocs;
   191 \<close> ML \<open>
   192 fun add_expr_pfuns funs = fold_expr
   193   (fn s => if is_pfun s then I else insert (op =) s)
   194   (fn s => if is_none (lookup funs s) then I else insert (op =) s);
   195 \<close> ML \<open>
   196 fun fold_vcs f vcs =
   197   VCtab.fold (fn (_, (_, _, ps, cs)) => fold f ps #> fold f cs) vcs;
   198 \<close> ML \<open>
   199 fun lookup_prfx "" tab s = Symtab.lookup tab s
   200   | lookup_prfx prfx tab s = (case Symtab.lookup tab s of
   201         NONE => Symtab.lookup tab (prfx ^ "__" ^ s)
   202       | x => x);
   203 \<close> ML \<open>
   204 fun pfuns_of_vcs prfx funs pfuns vcs =
   205   fold_vcs (add_expr_pfuns funs o snd) vcs [] |>
   206   filter (is_none o lookup_prfx prfx pfuns);
   207 \<close> ML \<open>
   208 fun pfuns_of_vcs prfx funs pfuns vcs =
   209   fold_vcs (add_expr_pfuns funs o snd) vcs [] |>
   210   filter (is_none o lookup_prfx prfx pfuns);
   211 \<close> ML \<open>
   212 structure VCs = Theory_Data
   213 (
   214   type T =
   215     {pfuns: ((string list * string) option * term) Symtab.table,
   216      type_map: (typ * (string * string) list) Symtab.table,
   217      env:
   218        {ctxt: Element.context_i list,
   219         defs: (binding * thm) list,
   220         types: fdl_type tab,
   221         funs: (string list * string) tab,
   222         pfuns: ((string list * string) option * term) Symtab.table,
   223         ids: (term * string) Symtab.table * Name.context,
   224         proving: bool,
   225         vcs: (string * thm list option *
   226           (string * expr) list * (string * expr) list) VCtab.table,
   227         path: Path.T,
   228         prefix: string} option}
   229   val empty : T = {pfuns = Symtab.empty, type_map = Symtab.empty, env = NONE}
   230   val extend = I
   231   fun merge ({pfuns = pfuns1, type_map = type_map1, env = NONE},
   232         {pfuns = pfuns2, type_map = type_map2, env = NONE}) =
   233         {pfuns = Symtab.merge (eq_pair (op =) (op aconv)) (pfuns1, pfuns2),
   234          type_map = Symtab.merge (op =) (type_map1, type_map2),
   235          env = NONE}
   236     | merge _ = err_unfinished ()
   237 )
   238 \<close> ML \<open>
   239 fun get_type thy prfx ty =
   240   let val {type_map, ...} = VCs.get thy
   241   in lookup_prfx prfx type_map ty end;
   242 \<close> ML \<open>
   243 fun mk_type' _ _ "integer" = (HOLogic.intT, [])
   244   | mk_type' _ _ "boolean" = (HOLogic.boolT, [])
   245   | mk_type' thy prfx ty =
   246       (case get_type thy prfx ty of
   247          NONE =>
   248            (Syntax.check_typ (Proof_Context.init_global thy)
   249               (Type (Sign.full_name thy (Binding.name ty), [])),
   250             [])
   251        | SOME p => p);
   252 \<close> ML \<open>
   253 fun mk_type thy prfx ty = fst (mk_type' thy prfx ty);
   254 \<close> ML \<open>
   255 fun pfun_type thy prfx (argtys, resty) =
   256   map (mk_type thy prfx) argtys ---> mk_type thy prfx resty;
   257 \<close> ML \<open>
   258 fun declare_missing_pfuns thy prfx funs pfuns vcs (tab, ctxt) =
   259   let
   260     val (fs, (tys, Ts)) =
   261       pfuns_of_vcs prfx funs pfuns vcs |>
   262       map_filter (fn s => lookup funs s |>
   263         Option.map (fn ty => (s, (SOME ty, pfun_type thy prfx ty)))) |>
   264       split_list ||> split_list;
   265     val (fs', ctxt') = fold_map Name.variant fs ctxt
   266   in
   267     (fold Symtab.update_new (fs ~~ (tys ~~ map Free (fs' ~~ Ts))) pfuns,
   268      Element.Fixes (map2 (fn s => fn T =>
   269        (Binding.name s, SOME T, NoSyn)) fs' Ts),
   270      (tab, ctxt'))
   271   end;
   272 \<close> ML \<open>
   273 fun strip_underscores s =
   274   strip_underscores (unsuffix "_" s) handle Fail _ => s;
   275 
   276 fun strip_tilde s =
   277   unsuffix "~" s ^ "_init" handle Fail _ => s;
   278 \<close> ML \<open>
   279 val mangle_name = strip_underscores #> strip_tilde;
   280 \<close> ML \<open>
   281 fun mk_variables thy prfx xs ty (tab, ctxt) =
   282   let
   283     val T = mk_type thy prfx ty;
   284     val (ys, ctxt') = fold_map Name.variant (map mangle_name xs) ctxt;
   285     val zs = map (Free o rpair T) ys;
   286   in (zs, (fold (Symtab.update o apsnd (rpair ty)) (xs ~~ zs) tab, ctxt')) end;
   287 \<close> ML \<open>
   288 fun mk_unop s t =
   289   let val T = fastype_of t
   290   in Const (s, T --> T) $ t end;
   291 \<close> ML \<open>
   292 val booleanN = "boolean";
   293 val integerN = "integer";
   294 \<close> ML \<open>
   295 val to_lower = raw_explode #> map Symbol.to_ascii_lower #> implode;
   296 val lcase_eq = (op =) o apply2 (to_lower o Long_Name.base_name);
   297 \<close> ML \<open>
   298 fun find_field [] fname fields =
   299       find_first (curry lcase_eq fname o fst) fields
   300   | find_field cmap fname fields =
   301       (case AList.lookup (op =) cmap fname of
   302          NONE => NONE
   303        | SOME fname' => SOME (fname', the (AList.lookup (op =) fields fname')));
   304 \<close> ML \<open>
   305 fun get_record_info thy T = (case Record.dest_recTs T of
   306     [(tyname, [\<^typ>\<open>unit\<close>])] =>
   307       Record.get_info thy (Long_Name.qualifier tyname)
   308   | _ => NONE);
   309 \<close> ML \<open>
   310 fun find_field' fname = get_first (fn (flds, fldty) =>
   311   if member (op =) flds fname then SOME fldty else NONE);
   312 \<close> ML \<open>
   313 fun invert_map [] = I
   314   | invert_map cmap =
   315       map (apfst (the o AList.lookup (op =) (map swap cmap)));
   316 \<close> ML \<open>
   317 fun mk_times (t, u) =
   318   let
   319     val setT = fastype_of t;
   320     val T = HOLogic.dest_setT setT;
   321     val U = HOLogic.dest_setT (fastype_of u)
   322   in
   323     Const (\<^const_name>\<open>Sigma\<close>, setT --> (T --> HOLogic.mk_setT U) -->
   324       HOLogic.mk_setT (HOLogic.mk_prodT (T, U))) $ t $ Abs ("", T, u)
   325   end;
   326 \<close> ML \<open>
   327 fun term_of_expr thy prfx types pfuns =
   328   let
   329     fun tm_of vs (Funct ("->", [e, e'])) =
   330           (HOLogic.mk_imp (fst (tm_of vs e), fst (tm_of vs e')), booleanN)
   331 
   332       | tm_of vs (Funct ("<->", [e, e'])) =
   333           (HOLogic.mk_eq (fst (tm_of vs e), fst (tm_of vs e')), booleanN)
   334 
   335       | tm_of vs (Funct ("or", [e, e'])) =
   336           (HOLogic.mk_disj (fst (tm_of vs e), fst (tm_of vs e')), booleanN)
   337 
   338       | tm_of vs (Funct ("and", [e, e'])) =
   339           (HOLogic.mk_conj (fst (tm_of vs e), fst (tm_of vs e')), booleanN)
   340 
   341       | tm_of vs (Funct ("not", [e])) =
   342           (HOLogic.mk_not (fst (tm_of vs e)), booleanN)
   343 
   344       | tm_of vs (Funct ("=", [e, e'])) =
   345           (HOLogic.mk_eq (fst (tm_of vs e), fst (tm_of vs e')), booleanN)
   346 
   347       | tm_of vs (Funct ("<>", [e, e'])) = (HOLogic.mk_not
   348           (HOLogic.mk_eq (fst (tm_of vs e), fst (tm_of vs e'))), booleanN)
   349 
   350       | tm_of vs (Funct ("<", [e, e'])) = (HOLogic.mk_binrel \<^const_name>\<open>less\<close>
   351           (fst (tm_of vs e), fst (tm_of vs e')), booleanN)
   352 
   353       | tm_of vs (Funct (">", [e, e'])) = (HOLogic.mk_binrel \<^const_name>\<open>less\<close>
   354           (fst (tm_of vs e'), fst (tm_of vs e)), booleanN)
   355 
   356       | tm_of vs (Funct ("<=", [e, e'])) = (HOLogic.mk_binrel \<^const_name>\<open>less_eq\<close>
   357           (fst (tm_of vs e), fst (tm_of vs e')), booleanN)
   358 
   359       | tm_of vs (Funct (">=", [e, e'])) = (HOLogic.mk_binrel \<^const_name>\<open>less_eq\<close>
   360           (fst (tm_of vs e'), fst (tm_of vs e)), booleanN)
   361 
   362       | tm_of vs (Funct ("+", [e, e'])) = (HOLogic.mk_binop \<^const_name>\<open>plus\<close>
   363           (fst (tm_of vs e), fst (tm_of vs e')), integerN)
   364 
   365       | tm_of vs (Funct ("-", [e, e'])) = (HOLogic.mk_binop \<^const_name>\<open>minus\<close>
   366           (fst (tm_of vs e), fst (tm_of vs e')), integerN)
   367 
   368       | tm_of vs (Funct ("*", [e, e'])) = (HOLogic.mk_binop \<^const_name>\<open>times\<close>
   369           (fst (tm_of vs e), fst (tm_of vs e')), integerN)
   370 
   371       | tm_of vs (Funct ("/", [e, e'])) = (HOLogic.mk_binop \<^const_name>\<open>divide\<close>
   372           (fst (tm_of vs e), fst (tm_of vs e')), integerN)
   373 
   374       | tm_of vs (Funct ("div", [e, e'])) = (HOLogic.mk_binop \<^const_name>\<open>sdiv\<close>
   375           (fst (tm_of vs e), fst (tm_of vs e')), integerN)
   376 
   377       | tm_of vs (Funct ("mod", [e, e'])) = (HOLogic.mk_binop \<^const_name>\<open>modulo\<close>
   378           (fst (tm_of vs e), fst (tm_of vs e')), integerN)
   379 
   380       | tm_of vs (Funct ("-", [e])) =
   381           (mk_unop \<^const_name>\<open>uminus\<close> (fst (tm_of vs e)), integerN)
   382 
   383       | tm_of vs (Funct ("**", [e, e'])) =
   384           (Const (\<^const_name>\<open>power\<close>, HOLogic.intT --> HOLogic.natT -->
   385              HOLogic.intT) $ fst (tm_of vs e) $
   386                (\<^const>\<open>nat\<close> $ fst (tm_of vs e')), integerN)
   387 
   388       | tm_of (tab, _) (Ident s) =
   389           (case Symtab.lookup tab s of
   390              SOME t_ty => t_ty
   391            | NONE => (case lookup_prfx prfx pfuns s of
   392                SOME (SOME ([], resty), t) => (t, resty)
   393              | _ => error ("Undeclared identifier " ^ s)))
   394 
   395       | tm_of _ (Number i) = (HOLogic.mk_number HOLogic.intT i, integerN)
   396 
   397       | tm_of vs (Quantifier (s, xs, ty, e)) =
   398           let
   399             val (ys, vs') = mk_variables thy prfx xs ty vs;
   400             val q = (case s of
   401                 "for_all" => HOLogic.mk_all
   402               | "for_some" => HOLogic.mk_exists)
   403           in
   404             (fold_rev (fn Free (x, T) => fn t => q (x, T, t))
   405                ys (fst (tm_of vs' e)),
   406              booleanN)
   407           end
   408 
   409       | tm_of vs (Funct (s, es)) =
   410 
   411           (* record field selection *)
   412           (case try (unprefix "fld_") s of
   413              SOME fname => (case es of
   414                [e] =>
   415                  let
   416                    val (t, rcdty) = tm_of vs e;
   417                    val (rT, cmap) = mk_type' thy prfx rcdty
   418                  in case (get_record_info thy rT, lookup types rcdty) of
   419                      (SOME {fields, ...}, SOME (Record_Type fldtys)) =>
   420                        (case (find_field cmap fname fields,
   421                             find_field' fname fldtys) of
   422                           (SOME (fname', fT), SOME fldty) =>
   423                             (Const (fname', rT --> fT) $ t, fldty)
   424                         | _ => error ("Record " ^ rcdty ^
   425                             " has no field named " ^ fname))
   426                    | _ => error (rcdty ^ " is not a record type")
   427                  end
   428              | _ => error ("Function " ^ s ^ " expects one argument"))
   429            | NONE =>
   430 
   431           (* record field update *)
   432           (case try (unprefix "upf_") s of
   433              SOME fname => (case es of
   434                [e, e'] =>
   435                  let
   436                    val (t, rcdty) = tm_of vs e;
   437                    val (rT, cmap) = mk_type' thy prfx rcdty;
   438                    val (u, fldty) = tm_of vs e';
   439                    val fT = mk_type thy prfx fldty
   440                  in case get_record_info thy rT of
   441                      SOME {fields, ...} =>
   442                        (case find_field cmap fname fields of
   443                           SOME (fname', fU) =>
   444                             if fT = fU then
   445                               (Const (fname' ^ "_update",
   446                                  (fT --> fT) --> rT --> rT) $
   447                                    Abs ("x", fT, u) $ t,
   448                                rcdty)
   449                             else error ("Type\n" ^
   450                               Syntax.string_of_typ_global thy fT ^
   451                               "\ndoes not match type\n" ^
   452                               Syntax.string_of_typ_global thy fU ^
   453                               "\nof field " ^ fname)
   454                         | NONE => error ("Record " ^ rcdty ^
   455                             " has no field named " ^ fname))
   456                    | _ => error (rcdty ^ " is not a record type")
   457                  end
   458              | _ => error ("Function " ^ s ^ " expects two arguments"))
   459            | NONE =>
   460 
   461           (* enumeration type to integer *)
   462           (case try (unsuffix "__pos") s of
   463              SOME tyname => (case es of
   464                [e] => (Const (\<^const_name>\<open>pos\<close>,
   465                    mk_type thy prfx tyname --> HOLogic.intT) $ fst (tm_of vs e),
   466                  integerN)
   467              | _ => error ("Function " ^ s ^ " expects one argument"))
   468            | NONE =>
   469 
   470           (* integer to enumeration type *)
   471           (case try (unsuffix "__val") s of
   472              SOME tyname => (case es of
   473                [e] => (Const (\<^const_name>\<open>val\<close>,
   474                    HOLogic.intT --> mk_type thy prfx tyname) $ fst (tm_of vs e),
   475                  tyname)
   476              | _ => error ("Function " ^ s ^ " expects one argument"))
   477            | NONE =>
   478 
   479           (* successor / predecessor of enumeration type element *)
   480           if s = "succ" orelse s = "pred" then (case es of
   481               [e] =>
   482                 let
   483                   val (t, tyname) = tm_of vs e;
   484                   val T = mk_type thy prfx tyname
   485                 in (Const
   486                   (if s = "succ" then \<^const_name>\<open>succ\<close>
   487                    else \<^const_name>\<open>pred\<close>, T --> T) $ t, tyname)
   488                 end
   489             | _ => error ("Function " ^ s ^ " expects one argument"))
   490 
   491           (* user-defined proof function *)
   492           else
   493             (case lookup_prfx prfx pfuns s of
   494                SOME (SOME (_, resty), t) =>
   495                  (list_comb (t, map (fst o tm_of vs) es), resty)
   496              | _ => error ("Undeclared proof function " ^ s))))))
   497 
   498       | tm_of vs (Element (e, es)) =
   499           let val (t, ty) = tm_of vs e
   500           in case lookup types ty of
   501               SOME (Array_Type (_, elty)) =>
   502                 (t $ foldr1 HOLogic.mk_prod (map (fst o tm_of vs) es), elty)
   503             | _ => error (ty ^ " is not an array type")
   504           end
   505 
   506       | tm_of vs (Update (e, es, e')) =
   507           let val (t, ty) = tm_of vs e
   508           in case lookup types ty of
   509               SOME (Array_Type (idxtys, elty)) =>
   510                 let
   511                   val T = foldr1 HOLogic.mk_prodT
   512                     (map (mk_type thy prfx) idxtys);
   513                   val U = mk_type thy prfx elty;
   514                   val fT = T --> U
   515                 in
   516                   (Const (\<^const_name>\<open>fun_upd\<close>, fT --> T --> U --> fT) $
   517                      t $ foldr1 HOLogic.mk_prod (map (fst o tm_of vs) es) $
   518                        fst (tm_of vs e'),
   519                    ty)
   520                 end
   521             | _ => error (ty ^ " is not an array type")
   522           end
   523 
   524       | tm_of vs (Record (s, flds)) =
   525           let
   526             val (T, cmap) = mk_type' thy prfx s;
   527             val {extension = (ext_name, _), fields, ...} =
   528               (case get_record_info thy T of
   529                  NONE => error (s ^ " is not a record type")
   530                | SOME info => info);
   531             val flds' = map (apsnd (tm_of vs)) flds;
   532             val fnames = fields |> invert_map cmap |>
   533               map (Long_Name.base_name o fst);
   534             val fnames' = map fst flds;
   535             val (fvals, ftys) = split_list (map (fn s' =>
   536               case AList.lookup lcase_eq flds' s' of
   537                 SOME fval_ty => fval_ty
   538               | NONE => error ("Field " ^ s' ^ " missing in record " ^ s))
   539                   fnames);
   540             val _ = (case subtract lcase_eq fnames fnames' of
   541                 [] => ()
   542               | xs => error ("Extra field(s) " ^ commas xs ^
   543                   " in record " ^ s));
   544             val _ = (case duplicates (op =) fnames' of
   545                 [] => ()
   546               | xs => error ("Duplicate field(s) " ^ commas xs ^
   547                   " in record " ^ s))
   548           in
   549             (list_comb
   550                (Const (ext_name,
   551                   map (mk_type thy prfx) ftys @ [HOLogic.unitT] ---> T),
   552                 fvals @ [HOLogic.unit]),
   553              s)
   554           end
   555 
   556       | tm_of vs (Array (s, default, assocs)) =
   557           (case lookup types s of
   558              SOME (Array_Type (idxtys, elty)) =>
   559                let
   560                  val Ts = map (mk_type thy prfx) idxtys;
   561                  val T = foldr1 HOLogic.mk_prodT Ts;
   562                  val U = mk_type thy prfx elty;
   563                  fun mk_idx' T (e, NONE) = HOLogic.mk_set T [fst (tm_of vs e)]
   564                    | mk_idx' T (e, SOME e') = Const (\<^const_name>\<open>atLeastAtMost\<close>,
   565                        T --> T --> HOLogic.mk_setT T) $
   566                          fst (tm_of vs e) $ fst (tm_of vs e');
   567                  fun mk_idx idx =
   568                    if length Ts <> length idx then
   569                      error ("Arity mismatch in construction of array " ^ s)
   570                    else foldr1 mk_times (map2 mk_idx' Ts idx);
   571                  fun mk_upd (idxs, e) t =
   572                    if length idxs = 1 andalso forall (is_none o snd) (hd idxs)
   573                    then
   574                      Const (\<^const_name>\<open>fun_upd\<close>, (T --> U) -->
   575                          T --> U --> T --> U) $ t $
   576                        foldl1 HOLogic.mk_prod
   577                          (map (fst o tm_of vs o fst) (hd idxs)) $
   578                        fst (tm_of vs e)
   579                    else
   580                      Const (\<^const_name>\<open>fun_upds\<close>, (T --> U) -->
   581                          HOLogic.mk_setT T --> U --> T --> U) $ t $
   582                        foldl1 (HOLogic.mk_binop \<^const_name>\<open>sup\<close>)
   583                          (map mk_idx idxs) $
   584                        fst (tm_of vs e)
   585                in
   586                  (fold mk_upd assocs
   587                     (case default of
   588                        SOME e => Abs ("x", T, fst (tm_of vs e))
   589                      | NONE => Const (\<^const_name>\<open>undefined\<close>, T --> U)),
   590                   s)
   591                end
   592            | _ => error (s ^ " is not an array type"))
   593 
   594   in tm_of end;
   595 \<close> ML \<open>
   596 fun mk_pat s = (case Int.fromString s of
   597     SOME i => [HOLogic.mk_Trueprop (Var (("C", i), HOLogic.boolT))]
   598   | NONE => error ("Bad conclusion identifier: C" ^ s));
   599 \<close> ML \<open>
   600 fun mk_vc thy prfx types pfuns ids name_concl (tr, proved, ps, cs) =
   601   let val prop_of =
   602     HOLogic.mk_Trueprop o fst o term_of_expr thy prfx types pfuns ids
   603   in
   604     (tr, proved,
   605      Element.Assumes (map (fn (s', e) =>
   606        ((Binding.name ("H" ^ s'), []), [(prop_of e, [])])) ps),
   607      Element.Shows (map (fn (s', e) =>
   608        (if name_concl then (Binding.name ("C" ^ s'), [])
   609         else Binding.empty_atts,
   610         [(prop_of e, mk_pat s')])) cs))
   611   end;
   612 \<close> ML \<open>
   613 (*val lookup_vc: theory -> bool -> string -> (Element.context_i list *
   614     (string * thm list option * Element.context_i * Element.statement_i)) option
   615 *)
   616 fun lookup_vc thy name_concl name =
   617   (case VCs.get thy of
   618     {env = SOME {vcs, types, funs, pfuns, ids, ctxt, prefix, ...}, ...} =>
   619       (case VCtab.lookup vcs name of
   620          SOME vc =>
   621            let val (pfuns', ctxt', ids') =
   622              declare_missing_pfuns thy prefix funs pfuns vcs ids
   623            in
   624              SOME (ctxt @ [ctxt'],
   625                mk_vc thy prefix types pfuns' ids' name_concl vc)
   626            end
   627        | NONE => NONE)
   628   | _ => NONE);
   629 \<close> ML \<open>
   630 \<close> 
   631 subsubsection \<open>copied from spark_commands.ML\<close>
   632 ML \<open>
   633 \<close> ML \<open>
   634 fun get_vc thy vc_name =
   635   (case SPARK_VCs.lookup_vc thy false vc_name of
   636     SOME (ctxt, (_, proved, ctxt', stmt)) =>
   637       if is_some proved then
   638         error ("The verification condition " ^
   639           quote vc_name ^ " has already been proved.")
   640       else (ctxt @ [ctxt'], stmt)
   641   | NONE => error ("There is no verification condition " ^
   642       quote vc_name ^ "."));
   643 \<close> ML \<open>
   644 (*
   645 val prefer_input: ThyC.id * Problem.id -> References.T -> O_Model.T -> References.T * O_Model.T
   646 *)
   647 fun prefer_input (inthy, inpbl : Problem.id) (thy, pbl, met_id) o_model =
   648   if inthy = thy andalso inpbl = pbl
   649   then ((thy, pbl, met_id) : References.T, o_model)
   650   else ((inthy, inpbl, Method.id_empty), [])
   651 \<close> ML \<open>
   652 (*
   653 val prove_vc : string -> Proof.context -> Proof.state
   654 \<rightarrow>
   655 val prove_vc : string -> Proof.context -> Proof.state
   656 *)
   657 fun prove_vc vc_name lthy =
   658   let
   659     val _ = @{print} {a = "//--- Spark_Commands.prove_vc", vc_name = vc_name}
   660     val thy = Proof_Context.theory_of lthy;
   661     val (ctxt, stmt) = get_vc thy vc_name
   662 (*//--------------------------------- new code --------------------------------\\*)
   663     val refs'' = ("Biegelinie", ["Biegelinien"]) (*until Parse.name \<rightarrow> ParseC.problem_headline*)
   664     val refs' = Refs_Data.get thy
   665     val (refs as (_, pbl_id, _), o_model) = prefer_input refs'' refs' (OMod_Data.get thy)
   666     val i_model = I_Model.initPIDE pbl_id
   667 (*
   668   TODO: present Specification = i_model () + refs via PIDE
   669 *)
   670 (*----------------------------------- new code ----------------------------------*)
   671     val _ = @{print} {a = "prove_vc", o_model = o_model, refs = refs, i_model = i_model}
   672 (*\\--------------------------------- new code --------------------------------//*)
   673   in
   674     Specification.theorem true Thm.theoremK NONE
   675       (fn thmss => (Local_Theory.background_theory
   676          (SPARK_VCs.mark_proved vc_name (flat thmss))))
   677       (Binding.name vc_name, []) [] ctxt stmt false lthy
   678   end;
   679 \<close> ML \<open>
   680 \<close>
   681 
   682 section \<open>setup command_keyword \<close>
   683 ML \<open>
   684 \<close> ML \<open>
   685 val _ =                                                  
   686   Outer_Syntax.command \<^command_keyword>\<open>Example\<close> "start a Calculation from a Formalise-file"
   687     (Resources.provide_parse_files "Example" -- Parse.parname
   688       >> (Toplevel.theory o (load_formalisation ParseC.formalisation)));
   689 \<close> ML \<open>
   690 val _ =
   691   Outer_Syntax.local_theory_to_proof \<^command_keyword>\<open>Problem\<close>
   692     "start a Specification, either from scratch or from preceding 'Example'"
   693     (Parse.name >> prove_vc);
   694 \<close> ML \<open>
   695 \<close>
   696 
   697 subsection \<open>test runs with Example\<close>
   698 text \<open>
   699   Starting the Calculation for the Example requires session Isac with Isac.Biegelinie etc.
   700   So, do ~~$ ./zcoding-to-test.sh and use Test_Some.thy to evaluate
   701 
   702     Example \<open>/usr/local/isabisac/src/Tools/isac/Examples/exp_Statics_Biegel_Timischl_7-70\<close>
   703 
   704   This now gives no error, but also no <Output>. See child of 3ea616c84845.
   705 \<close>
   706 (*required for proof below..*)
   707 spark_proof_functions
   708   gcd = "gcd :: int \<Rightarrow> int \<Rightarrow> int"
   709 (**)
   710 spark_open \<open>~~/src/HOL/SPARK/Examples/Gcd/greatest_common_divisor/g_c_d\<close>
   711 (*Output..* )
   712 The following verification conditions remain to be proved:
   713   procedure_g_c_d_4
   714   procedure_g_c_d_11
   715 ( **)
   716 spark_vc procedure_g_c_d_4
   717 proof -
   718   from \<open>0 < d\<close> have "0 \<le> c mod d" by (rule pos_mod_sign)
   719   with \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>c - c sdiv d * d \<noteq> 0\<close> show ?C1
   720     by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric])
   721 (** )
   722 proof -
   723   from \<open>0 < d\<close> have "0 \<le> c mod d" by (rule pos_mod_sign)
   724   with \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>c - c sdiv d * d \<noteq> 0\<close> show ?C1
   725     by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric])
   726 next
   727   from \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>gcd c d = gcd m n\<close> show ?C2
   728     by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric] gcd_non_0_int)
   729 qed
   730 ( **)oops(**)
   731 (** )sorry( **)
   732 
   733 spark_vc procedure_g_c_d_11
   734   sorry
   735 (** )
   736 spark_end
   737 ( *Bad path binding: "$ISABELLE_HOME/src/HOL/SPARK/Examples/Gcd/greatest_common_divisor/g_c_d.prv"*)
   738 
   739 
   740 section \<open>adapt spark_vc to Problem\<close>
   741 
   742 subsection \<open>survey on steps of investigation\<close>
   743 text \<open>
   744 1.prove_vc: string -> Proof.context -> Proof.state
   745   ? where does        ^^^^^^^^^^^^^ come from:
   746   fun get_vc: (case SPARK_VCs.lookup_vc .. of SOME (ctxt, (_, proved, ctxt', stmt)) => ...
   747     
   748 \<close>
   749 
   750 subsection \<open>notes and testbed for spark_vcs\<close>
   751 ML \<open>
   752 \<close> ML \<open> (* Outer_Syntax.local_theory_to_proof..global_interpretationC *)
   753 val interpretation_args_with_defs =
   754   Parse.!!! Parse_Spec.locale_expression --
   755     (Scan.optional (\<^keyword>\<open>defines\<close> |-- Parse.and_list1 (Parse_Spec.opt_thm_name ":"
   756       -- ((Parse.binding -- Parse.opt_mixfix') --| \<^keyword>\<open>=\<close> -- Parse.term))) ([]));
   757 \<close> ML \<open>
   758   Outer_Syntax.local_theory_to_proof \<^command_keyword>\<open>global_interpretationC\<close>
   759     "prove interpretation of locale expression into global theory"
   760     (interpretation_args_with_defs >> (fn (expr, defs) =>
   761       Interpretation.global_interpretation_cmd expr defs));
   762 \<close> ML \<open>
   763     (interpretation_args_with_defs >> (fn (expr, defs) =>
   764       Interpretation.global_interpretation_cmd expr defs))
   765 : Token.T list -> (local_theory -> Proof.state) * Token.T list;
   766 \<close> ML \<open>
   767 \<close> ML \<open> (* Outer_Syntax.local_theory_to_proof..Problem *)
   768     (Parse.name >> prove_vc)
   769 : Token.T list -> (Proof.context -> Proof.state) * Token.T list;
   770 \<close> ML \<open>
   771 \<close> ML \<open>
   772 \<close>
   773 
   774 subsection \<open>testbed for Problem\<close>
   775 ML \<open>
   776 \<close> ML \<open>
   777 \<close> ML \<open>
   778 \<close> ML \<open>
   779 \<close> ML \<open>
   780 \<close> ML \<open>
   781 \<close> ML \<open>
   782 \<close> ML \<open>
   783 \<close>
   784 
   785 
   786 end
   787 (*
   788   ERROR: Found the end of the theory, but the last SPARK environment is still open.
   789   ..is OK, since "spark_end" does NOT work here for some reason.
   790 *)