src/Tools/isac/Interpret/lucas-interpreter.sml
author Walther Neuper <walther.neuper@jku.at>
Thu, 19 Dec 2019 17:37:25 +0100
changeset 59751 fa26464c66bf
parent 59749 cc3b1807f72e
child 59754 468633978eb9
permissions -rw-r--r--
lucin: unify fun.ids. for locate_input_tactic
wneuper@59562
     1
(* Title:  Interpret/lucas-interpreter.sml
wneuper@59554
     2
   Author: Walther Neuper 2019
wneuper@59554
     3
   (c) due to copyright terms
wneuper@59554
     4
*)
wneuper@59554
     5
wneuper@59554
     6
signature LUCAS_INTERPRETER =
wneuper@59554
     7
sig
walther@59747
     8
  datatype input_tactic_result =
walther@59747
     9
      Safe_Step of Istate.T * Proof.context * Tactic.T
walther@59655
    10
    | Unsafe_Step of Istate.T * Proof.context * Tactic.T
wneuper@59569
    11
    | Not_Locatable of string
walther@59734
    12
  val locate_input_tactic: Rule.program -> Ctree.state -> Istate.T -> Proof.context -> Tactic.T
wneuper@59569
    13
    -> input_tactic_result
wneuper@59557
    14
walther@59747
    15
  datatype next_tactic_result =
walther@59747
    16
      Next_Step of Istate.T * Proof.context * Tactic.T
walther@59734
    17
    | Helpless | End_Program of Istate.T * Tactic.T
walther@59743
    18
  val find_next_tactic: Rule.program -> Ctree.state -> Istate.T -> Proof.context
walther@59734
    19
    -> next_tactic_result
walther@59734
    20
walther@59749
    21
(*TODO      input_formula_result = Found_Step of  Ctree.state | Not_Derivable *)
wneuper@59562
    22
  datatype input_formula_result =
walther@59747
    23
    Found_Step of Ctree.state * Istate.T * Proof.context
wneuper@59562
    24
  | Not_Derivable of Chead.calcstate'
walther@59749
    25
(*TODOlocate_input_formula: Ctree.state -> term -> input_formula_result *)
walther@59734
    26
  val locate_input_formula: Rule.program -> Ctree.state -> Istate.T -> Proof.context -> term
wneuper@59562
    27
    -> input_formula_result
walther@59749
    28
                        
walther@59749
    29
  (* must reside here:
walther@59751
    30
     find_next_tactic calls do_solve_step and is called by by_tactic;
walther@59751
    31
     by_tactic and do_solve_step are mutually recursive via by_tactic Apply_Method'
walther@59749
    32
   *)
walther@59751
    33
  val by_tactic: Tactic.T -> Istate.T * Proof.context -> Ctree.state -> Chead.calcstate'
walther@59734
    34
  val do_solve_step: Ctree.state -> Chead.calcstate'
wneuper@59569
    35
wneuper@59557
    36
(* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
walther@59712
    37
  datatype expr_val1 =
walther@59718
    38
      Accept_Tac1 of Istate.pstate * Proof.context * Tactic.T
walther@59712
    39
    | Reject_Tac1 of Istate.pstate * Proof.context * Tactic.T
walther@59713
    40
    | Term_Val1 of term;
walther@59734
    41
  val assoc2str: expr_val1 -> string
walther@59702
    42
(*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
walther@59734
    43
  val go: Celem.path -> term -> term
walther@59687
    44
  val go_up: Celem.path -> term -> term
walther@59734
    45
  val check_Let_up: Istate.pstate -> term -> term * term
walther@59685
    46
  val check_Seq_up: Istate.pstate -> term -> term
walther@59734
    47
  val compare_step: Generate.taci list * Ctree.pos' list * (Ctree.state) -> term -> string * Chead.calcstate'
walther@59686
    48
walther@59712
    49
  val scan_dn1: (Ctree.state * Proof.context * Tactic.T) -> Istate.pstate -> term -> expr_val1
walther@59712
    50
  val scan_up1: term * (Ctree.state * Proof.context * Tactic.T) -> Istate.pstate -> term -> expr_val1;
walther@59712
    51
  val go_scan_up1: term * (Ctree.state * Proof.context * Tactic.T) -> Istate.pstate -> expr_val1;
walther@59712
    52
  val scan_to_tactic1: term * (Ctree.state * Proof.context * Tactic.T) -> Istate.T -> expr_val1
walther@59718
    53
  val interpret_tac1: Ctree.state * Proof.context * Tactic.T -> Istate.pstate -> term option * term -> expr_val1
walther@59686
    54
walther@59728
    55
  datatype expr_val2 = Accept_Tac2 of Tactic.T * Istate.pstate * Proof.context
walther@59728
    56
    | Reject_Tac2 | Term_Val2 of term
walther@59722
    57
  val scan_dn2: Ctree.state * Proof.context -> Istate.pstate -> term -> expr_val2
walther@59722
    58
  val scan_up2: term * (Ctree.state * Proof.context) -> Istate.pstate -> term -> expr_val2
walther@59722
    59
  val go_scan_up2: term * (Ctree.state * Proof.context) -> Istate.pstate -> expr_val2
walther@59722
    60
  val scan_to_tactic2: term * (Ctree.state * Proof.context) -> Istate.T -> expr_val2
walther@59702
    61
( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
wneuper@59554
    62
end
wneuper@59554
    63
walther@59684
    64
(**)
wneuper@59557
    65
structure LucinNEW(**): LUCAS_INTERPRETER(**) = (*LucinNEW \<rightarrow> Lucin after code re-arrangement*)
wneuper@59554
    66
struct
walther@59684
    67
(**)
wneuper@59554
    68
open Ctree
walther@59695
    69
open Pos
walther@59659
    70
open Celem
walther@59661
    71
open Istate
wneuper@59554
    72
walther@59701
    73
(*** auxiliary functions ***)
wneuper@59567
    74
walther@59701
    75
(*go to a location in a program and fetch the resective sub-term*)
wneuper@59554
    76
fun go [] t = t
walther@59692
    77
  | go (D :: p) (Abs(_, _, body)) = go (p : Celem.path) body
walther@59661
    78
  | go (L :: p) (t1 $ _) = go p t1
walther@59661
    79
  | go (R :: p) (_ $ t2) = go p t2
walther@59687
    80
  | go l _ = error ("go: no " ^ Celem.path2str l);
walther@59668
    81
fun go_up l t =
walther@59668
    82
  if length l > 1 then go (drop_last l) t else raise ERROR ("go_up [] " ^ Rule.term2str t)
wneuper@59554
    83
walther@59685
    84
fun check_Let_up ({path, ...}: pstate) prog =
walther@59668
    85
  case go (drop_last path) prog of
walther@59664
    86
    Const ("HOL.Let",_) $ _ $ (Abs (i, T, body)) => (TermC.mk_Free (i, T), body)
walther@59691
    87
  | t => raise ERROR ("scan_up1..\"HOL.Let $ _\" with: \"" ^ Rule.term2str t ^ "\"")
walther@59685
    88
fun check_Seq_up  ({path, ...}: pstate) prog =
walther@59664
    89
  case go (drop_last path) prog of
walther@59688
    90
    Const ("Tactical.Chain",_) $ _ $ e2=> e2
walther@59691
    91
  | t => raise ERROR ("scan_up1..\"Tactical.Chain $ _\" with: \"" ^ Rule.term2str t ^ "\"")
walther@59691
    92
walther@59701
    93
walther@59701
    94
(*** locate an input tactic within a program ***)
walther@59691
    95
walther@59691
    96
datatype input_tactic_result =
walther@59691
    97
    Safe_Step of Istate.T * Proof.context * Tactic.T
walther@59691
    98
  | Unsafe_Step of Istate.T * Proof.context * Tactic.T
walther@59691
    99
  | Not_Locatable of string
walther@59691
   100
walther@59712
   101
datatype expr_val1 = (* "ExprVal" in the sense of denotational semantics        *)
walther@59712
   102
  Reject_Tac1 of     (* tactic is found but NOT acknowledged, scan is continued *)
walther@59716
   103
    Istate.pstate * Proof.context * Tactic.T (*TODO: revise Pstate {or,...},no args as Reject_Tac2*)
walther@59718
   104
| Accept_Tac1 of       (* tactic is found and acknowledged, scan is stalled       *)
walther@59712
   105
    Istate.pstate *  (* the current state, returned for resuming execution      *)
walther@59712
   106
    Proof.context *  (* updated according to evaluation of Prog_Tac             *)
walther@59712
   107
    Tactic.T         (* Prog_Tac is associated to Tactic.input                  *)
walther@59712
   108
| Term_Val1 of       (* Prog_Expr is found and evaluated, scan is continued     *)
walther@59712
   109
	  term             (* value of Prog_Expr, for updating environment            *)
walther@59718
   110
fun assoc2str (Accept_Tac1 _) = "Accept_Tac1"                                         
walther@59712
   111
  | assoc2str (Term_Val1 _) = "Term_Val1"
walther@59712
   112
  | assoc2str (Reject_Tac1 _) = "Reject_Tac1";
walther@59691
   113
walther@59701
   114
walther@59718
   115
(** interpret a Prog_Tac: is it associated to Tactic ? **)
walther@59718
   116
walther@59718
   117
fun interpret_tac1 ((pt, p), ctxt, tac) (ist as {act_arg, or, ...}) (form_arg, prog_tac) =
walther@59718
   118
  case Lucin.associate pt ctxt (tac, prog_tac) of
walther@59718
   119
     (* HERE ----------------vvvv ContextC.insert_assumptions asm ctxt DONE -- 2nd in gen//*)
walther@59718
   120
      Lucin.Ass      (m, v', ctxt) => Accept_Tac1 (ist |> set_subst_true  (form_arg, v'), ctxt, m)
walther@59718
   121
    | Lucin.Ass_Weak (m, v', ctxt) => Accept_Tac1 (ist |> set_subst_false (form_arg, v'), ctxt, m)
walther@59718
   122
walther@59718
   123
    | Lucin.NotAss =>
walther@59718
   124
      (case or of (* switch for Tactical.Or: 1st AssOnly, 2nd AssGen *)
walther@59718
   125
         AssOnly => Term_Val1 act_arg
walther@59718
   126
       | _(*ORundef*) =>
walther@59718
   127
          case Applicable.applicable_in p pt (Lucin.stac2tac pt (Celem.assoc_thy "Isac_Knowledge") prog_tac) of
walther@59735
   128
             Applicable.Appl m' => Reject_Tac1 (ist |> set_subst_false (form_arg, Tactic.result m'), ctxt, tac)
walther@59735
   129
           | Applicable.Notappl _ => Term_Val1 act_arg)
walther@59718
   130
walther@59701
   131
(** scan to a Prog_Tac **)
walther@59701
   132
walther@59700
   133
fun scan_dn1 cct ist (Const ("Tactical.Try"(*1*), _) $ e $ a) =
walther@59701
   134
    (case scan_dn1 cct (ist |> path_down_form ([L, R], a)) e of goback => goback) 
walther@59700
   135
  | scan_dn1 cct ist (Const ("Tactical.Try"(*2*), _) $ e) =
walther@59701
   136
    (case scan_dn1 cct (ist |> path_down [R]) e of goback => goback)
walther@59691
   137
walther@59700
   138
  | scan_dn1 cct ist (Const ("Tactical.Repeat"(*1*), _) $ e $ a) =
walther@59701
   139
    scan_dn1 cct (ist |> path_down_form ([L, R], a)) e
walther@59700
   140
  | scan_dn1 cct ist (Const ("Tactical.Repeat"(*2*), _) $ e) =
walther@59700
   141
    scan_dn1 cct (ist |> path_down [R]) e
walther@59691
   142
walther@59709
   143
  | scan_dn1 (cct as (cstate, _, _)) ist (Const ("Tactical.Chain"(*1*), _) $ e1 $ e2 $ a) =
walther@59700
   144
    (case scan_dn1 cct (ist |> path_down_form ([L, L, R], a)) e1 of
walther@59712
   145
	     Term_Val1 v => scan_dn1 cct (ist |> path_down [L, R] |> set_subst' (a, v)) e2
walther@59712
   146
     | Reject_Tac1 (ist', ctxt', tac') => scan_dn1 (cstate, ctxt', tac') (ist
walther@59712
   147
        |> path_down_form ([L, R], a) |> trans_env_act ist') e2
walther@59701
   148
     | goback => goback)
walther@59709
   149
  | scan_dn1 (cct as (cstate, _, _)) ist (Const ("Tactical.Chain"(*2*), _) $e1 $ e2) =
walther@59700
   150
    (case scan_dn1 cct (ist |> path_down [L, R]) e1 of
walther@59712
   151
	     Term_Val1 v => scan_dn1 cct (ist |> path_down [R] |> set_act v) e2
walther@59712
   152
     | Reject_Tac1 (ist', ctxt', tac') =>
walther@59712
   153
        scan_dn1 (cstate, ctxt', tac') (ist |> path_down [R] |> trans_env_act ist') e2
walther@59701
   154
     | goback => goback)
walther@59691
   155
walther@59709
   156
  | scan_dn1 cct ist (Const ("HOL.Let", _) $ e $ (Abs (id, T, b))) =
walther@59700
   157
    (case scan_dn1 cct (ist |> path_down [L, R]) e of
walther@59712
   158
       Reject_Tac1 (ist', _, _) =>
walther@59700
   159
         scan_dn1 cct (ist' |> path_down [R, D] |> upd_env (TermC.mk_Free (id, T)) |> trans_ass ist) b
walther@59712
   160
     | Term_Val1 v =>
walther@59709
   161
         scan_dn1 cct (ist |> path_down [R, D] |> upd_env'' (TermC.mk_Free (id, T), v)) b
walther@59703
   162
     | goback => goback)
walther@59691
   163
walther@59722
   164
  | scan_dn1 (cct as (_, ctxt, _)) (ist as {eval, act_arg, ...})
walther@59722
   165
      (Const ("Tactical.While"(*1*), _) $ c $ e $ a) =
walther@59722
   166
    if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval
walther@59697
   167
      (subst_atomic (ist |> get_act_env |> Env.update' a) c)
walther@59703
   168
    then scan_dn1 cct (ist |> path_down_form ([L, R], a)) e
walther@59712
   169
    else Term_Val1 act_arg
walther@59722
   170
  | scan_dn1 (cct as (_, ctxt, _)) (ist as {eval, act_arg, ...})
walther@59722
   171
      (Const ("Tactical.While"(*2*),_) $ c $ e) =
walther@59722
   172
    if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c) 
walther@59700
   173
    then scan_dn1 cct (ist |> path_down [R]) e
walther@59712
   174
    else Term_Val1 act_arg
walther@59691
   175
walther@59718
   176
  | scan_dn1 cct (ist as {or = ORundef, ...}) (Const ("Tactical.Or"(*1*), _) $e1 $ e2 $ a) =
walther@59700
   177
    (case scan_dn1 cct (ist |> path_down_form ([L, L, R], a) |> set_or AssOnly) e1 of
walther@59712
   178
	     Term_Val1 v =>
walther@59709
   179
	       (case scan_dn1 cct (ist |> path_down [L, R] |> set_subst' (a, v) |> set_or AssOnly) e2 of
walther@59712
   180
	          Term_Val1 v => 
walther@59709
   181
	            (case scan_dn1 cct (ist |> path_down [L, L, R] |> upd_env'' (a, v) |> set_or AssGen) e1 of
walther@59712
   182
	               Term_Val1 v => 
walther@59709
   183
	                 scan_dn1 cct (ist |> path_down [L, R] |> upd_env'' (a, v) |> set_or AssGen) e2
walther@59703
   184
	             | goback => goback)
walther@59703
   185
	        | goback => goback)
walther@59712
   186
     | Reject_Tac1 _ => raise ERROR ("scan_dn1 Tactical.Or(*1*): must not return Reject_Tac1")
walther@59703
   187
     | goback => goback)
walther@59710
   188
  | scan_dn1 cct ist (Const ("Tactical.Or"(*2*), _) $e1 $ e2) =
walther@59700
   189
    (case scan_dn1 cct (ist |> path_down [L, R]) e1 of
walther@59712
   190
	     Term_Val1 v => scan_dn1 cct (ist |> path_down [R] |> set_act v) e2
walther@59703
   191
     | goback => goback)
walther@59691
   192
walther@59722
   193
  | scan_dn1 (cct as (_, ctxt, _)) (ist as {eval, ...}) (Const ("Tactical.If", _) $ c $ e1 $ e2) =
walther@59722
   194
    if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
walther@59700
   195
    then scan_dn1 cct (ist |> path_down [L, R]) e1
walther@59700
   196
    else scan_dn1 cct (ist |> path_down [R]) e2
walther@59691
   197
walther@59719
   198
  | scan_dn1 (cct as (_, ctxt, _)) (ist as {eval, ...}) t =
walther@59716
   199
    if Tactical.contained_in t then raise TERM ("scan_dn1 expects Prog_Tac or Prog_Expr", [t])
walther@59717
   200
    else
walther@59722
   201
      case Lucin.interpret_leaf "locate" ctxt eval (get_subst ist) t of
walther@59731
   202
  	    (Program.Expr _, form_arg) => 
walther@59731
   203
  	      Term_Val1 (Rewrite.eval_prog_expr (Proof_Context.theory_of ctxt) eval
walther@59731
   204
  		      (subst_atomic (Env.update_opt'' (get_act_env ist, form_arg)) t))
walther@59731
   205
      | (Program.Tac prog_tac, form_arg) =>
walther@59731
   206
          interpret_tac1 cct ist (form_arg, prog_tac)
walther@59691
   207
walther@59720
   208
fun go_scan_up1 (pcct as (prog, _)) (ist as {path, act_arg, ...}) =
walther@59720
   209
    if 1 < length path
walther@59720
   210
    then scan_up1 pcct (ist |> path_up) (go (path_up' path) prog)
walther@59720
   211
    else Term_Val1 act_arg
walther@59720
   212
and scan_up1 pcct ist (Const ("Tactical.Try"(*1*), _) $ _ $ _) = go_scan_up1 pcct ist
walther@59700
   213
  | scan_up1 pcct ist (Const ("Tactical.Try"(*2*), _) $ _) = go_scan_up1 pcct ist
walther@59691
   214
walther@59709
   215
  | scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (t as Const ("Tactical.Repeat"(*1*), _) $ e $ a) =
walther@59718
   216
    (case scan_dn1 cct (ist |> path_down_form ([L, R], a) |> set_or ORundef) e of 
walther@59712
   217
      Term_Val1 v => go_scan_up1 pcct (ist |> set_act v |> set_form a)
walther@59712
   218
    | Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
walther@59703
   219
    | goback => goback)
walther@59710
   220
  | scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (t as Const ("Tactical.Repeat"(*2*), _) $ e) =
walther@59718
   221
    (case scan_dn1 cct (ist |> path_down [R] |> set_or ORundef) e of
walther@59712
   222
       Term_Val1 v' => go_scan_up1 pcct (ist |> set_act v')
walther@59712
   223
     | Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
walther@59703
   224
     | goback => goback)
walther@59691
   225
walther@59703
   226
    (*all has been done in (*2*) below*)
walther@59700
   227
  | scan_up1 pcct ist (Const ("Tactical.Chain"(*1*), _) $ _ $ _ $ _) = go_scan_up1 pcct ist
walther@59718
   228
  | scan_up1 pcct ist (Const ("Tactical.Chain"(*2*), _) $ _ $ _) = go_scan_up1 pcct ist (*comes from e2*)    
walther@59709
   229
  | scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (Const ("Tactical.Chain"(*3*), _) $ _ ) =
walther@59691
   230
     let 
walther@59718
   231
       val e2 = check_Seq_up ist prog (*comes from e1, goes to e2*)
walther@59691
   232
     in
walther@59718
   233
       case scan_dn1 cct (ist |> path_up_down [R] |> set_or ORundef) e2 of
walther@59712
   234
         Term_Val1 v => go_scan_up1 pcct (ist |> path_up |> set_act v)
walther@59712
   235
       | Reject_Tac1 (ist', ctxt', tac') => go_scan_up1 (prog, (cstate, ctxt', tac')) ist'
walther@59703
   236
       | goback => goback 
walther@59691
   237
     end
walther@59691
   238
walther@59709
   239
  | scan_up1 (pcct as (prog, cct as (cstate, _, _))) ist (Const ("HOL.Let"(*1*), _) $ _) =
walther@59691
   240
    let 
walther@59692
   241
      val (i, body) = check_Let_up ist prog
walther@59718
   242
    in case scan_dn1 cct (ist |> path_up_down [R, D] |> upd_env i |> set_or ORundef) body of
walther@59718
   243
	       Accept_Tac1 iss => Accept_Tac1 iss
walther@59712
   244
	     | Reject_Tac1 (ist', ctxt', tac') => go_scan_up1 (prog, (cstate, ctxt', tac')) ist'
walther@59712
   245
	     | Term_Val1 v => go_scan_up1 pcct (ist |> path_up |> set_act v) 
walther@59691
   246
	  end
walther@59700
   247
  | scan_up1 pcct ist (Abs(*2*) _) = go_scan_up1 pcct ist
walther@59700
   248
  | scan_up1 pcct ist (Const ("HOL.Let"(*3*), _) $ _ $ (Abs _)) = go_scan_up1 pcct ist
walther@59691
   249
walther@59722
   250
  | scan_up1 (pcct as (prog, cct as (cstate, ctxt, _))) (ist as {eval, ...})
walther@59703
   251
      (t as Const ("Tactical.While"(*1*),_) $ c $ e $ a) =
walther@59722
   252
    if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update' a (get_act_env ist)) c)
walther@59691
   253
    then
walther@59718
   254
      case scan_dn1 cct (ist |> path_down_form ([L, R], a) |> set_or ORundef) e of 
walther@59712
   255
        Term_Val1 v => go_scan_up1 pcct (ist |> set_act v |> set_form a)
walther@59691
   256
walther@59712
   257
      | Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
walther@59703
   258
      | goback => goback
walther@59700
   259
    else go_scan_up1 pcct (ist |> set_form a)
walther@59722
   260
  | scan_up1 (pcct as (prog, cct as (cstate, ctxt, _))) (ist as {eval, ...})
walther@59703
   261
      (t as Const ("Tactical.While"(*2*), _) $ c $ e) =
walther@59722
   262
    if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
walther@59691
   263
    then
walther@59718
   264
      case scan_dn1 cct (ist |> path_down [R] |> set_or ORundef) e of 
walther@59712
   265
        Term_Val1 v => go_scan_up1 pcct (ist |> set_act v)
walther@59712
   266
       | Reject_Tac1 (ist', ctxt', tac') => scan_up1 (prog, (cstate, ctxt', tac')) ist' t
walther@59703
   267
       | goback => goback
walther@59700
   268
    else go_scan_up1 pcct ist
walther@59691
   269
walther@59700
   270
  | scan_up1 pcct ist (Const ("If", _) $ _ $ _ $ _) = go_scan_up1 pcct ist
walther@59691
   271
walther@59700
   272
  | scan_up1 pcct ist (Const ("Tactical.Or"(*1*), _) $ _ $ _ $ _) = go_scan_up1 pcct ist
walther@59700
   273
  | scan_up1 pcct ist (Const ("Tactical.Or"(*2*), _) $ _ $ _) = go_scan_up1 pcct ist
walther@59700
   274
  | scan_up1 pcct ist (Const ("Tactical.Or"(*3*), _) $ _ ) = go_scan_up1 pcct (ist |> path_up)
walther@59691
   275
walther@59700
   276
  | scan_up1 pcct ist (Const ("Tactical.If",_) $ _ $ _ $ _) = go_scan_up1 pcct ist
walther@59691
   277
walther@59691
   278
  | scan_up1 _ _ t = error ("scan_up1 not impl for t= " ^ Rule.term2str t)
walther@59691
   279
walther@59692
   280
fun scan_to_tactic1 (prog, (cctt as ((_, p), _, _))) (Istate.Pstate (ist as {path, ...})) =
walther@59743
   281
    if path = [] orelse Pos.at_first_tactic(*RM prog path RM WITH find_next_tactic IN solve*)p
walther@59718
   282
    then scan_dn1 cctt (ist |> set_path [R] |> set_or ORundef) (Program.body_of prog)
walther@59692
   283
    else go_scan_up1 (prog, cctt) ist
walther@59691
   284
  | scan_to_tactic1 _ _ = raise ERROR "scan_to_tactic1: uncovered pattern in fun.def"
walther@59691
   285
walther@59701
   286
(*locate an input tactic within a program*)
walther@59699
   287
fun locate_input_tactic (Rule.Prog prog) cstate istate ctxt tac =
walther@59699
   288
    (case scan_to_tactic1 (prog, (cstate, ctxt, tac)) istate of
walther@59718
   289
         Accept_Tac1 ((ist as {assoc, ...}), ctxt, tac') =>
walther@59691
   290
          if assoc
walther@59691
   291
          then Safe_Step (Istate.Pstate ist, ctxt, tac')
walther@59691
   292
 	        else Unsafe_Step (Istate.Pstate ist, ctxt, tac')
walther@59728
   293
      | Reject_Tac1 _ => Not_Locatable (Tactic.string_of tac ^ " not locatable")
walther@59691
   294
      | err => raise ERROR ("not-found-in-script: NotLocatable from " ^ @{make_string} err))
walther@59691
   295
  | locate_input_tactic _ _ _ _ _ = raise ERROR "locate_input_tactic: uncovered case in definition"
walther@59691
   296
wneuper@59562
   297
walther@59701
   298
(*** determine a next tactic by executing the program ***)
wneuper@59554
   299
walther@59729
   300
  datatype next_tactic_result = Next_Step of Istate.T * Proof.context * Tactic.T
walther@59734
   301
    | Helpless | End_Program of Istate.T * Tactic.T (*contains prog_result, without asms*)
wneuper@59566
   302
walther@59712
   303
(** scan to a Prog_Tac **)
walther@59712
   304
walther@59728
   305
datatype expr_val2 = (* "ExprVal" in the sense of denotational semantics           *)
walther@59728
   306
  Reject_Tac2        (* tactic is found but NOT acknowledged, scan is continued    *)
walther@59728
   307
| Accept_Tac2 of     (* tactic is found and acknowledged, scan is stalled          *)
walther@59728
   308
    Tactic.T *       (* Prog_Tac is applicable_in cstate                           *)
walther@59728
   309
    Istate.pstate *  (* created by application of Tactic.T, for resuming execution *)
walther@59728
   310
    Proof.context    (* created by application of Tactic.T                         *)
walther@59728
   311
| Term_Val2 of       (* Prog_Expr is found and evaluated, scan is continued        *)
walther@59728
   312
    term;            (* value of Prog_Expr, for updating environment               *)
walther@59712
   313
walther@59701
   314
(*
walther@59743
   315
  scan_dn2, go_scan_up2, scan_up2 scan for find_next_tactic.
walther@59691
   316
  (1) scan_dn2 is recursive descent;
walther@59700
   317
  (2) go_scan_up2 goes to the parent node and calls (3);
walther@59700
   318
  (3) scan_up2 resumes according to the interpreter-state.
walther@59701
   319
  Call of (2) means that there was an applicable Prog_Tac below
wneuper@59554
   320
*)
walther@59711
   321
fun scan_dn2 cc (ist as {act_arg, ...}) (Const ("Tactical.Try"(*1*), _) $ e $ a) =
walther@59700
   322
    (case scan_dn2 cc (ist|> path_down_form ([L, R], a)) e of
walther@59712
   323
      Reject_Tac2 => Term_Val2 act_arg
walther@59722
   324
    | (*Accept_Tac2*) goback => goback)
walther@59711
   325
  | scan_dn2 cc (ist as {act_arg, ...}) (Const ("Tactical.Try"(*2*), _) $ e) =
walther@59700
   326
    (case scan_dn2 cc (ist |> path_down [R]) e of
walther@59712
   327
      Reject_Tac2 => Term_Val2 act_arg
walther@59722
   328
    | (*Accept_Tac2*) goback => goback)
walther@59689
   329
walther@59700
   330
  | scan_dn2 cc ist (Const ("Tactical.Repeat"(*1*), _) $ e $ a) = 
walther@59700
   331
    scan_dn2 cc (ist |> path_down_form ([L, R], a)) e
walther@59700
   332
  | scan_dn2 cc ist (Const ("Tactical.Repeat"(*2*), _) $ e) =
walther@59700
   333
    scan_dn2 cc (ist |> path_down [R]) e
walther@59689
   334
walther@59711
   335
  | scan_dn2 cc ist (Const ("Tactical.Chain"(*1*), _) $ e1 $ e2 $ a) =
walther@59700
   336
    (case scan_dn2 cc (ist |> path_down_form ([L, L, R], a)) e1 of
walther@59712
   337
	    Term_Val2 v => scan_dn2 cc (ist |> path_down_form ([L, R], a) |> set_act v) e2 (*UPD*)
walther@59722
   338
    | (*Accept_Tac2*) goback => goback)
walther@59711
   339
  | scan_dn2 cc ist (Const ("Tactical.Chain"(*2*), _) $ e1 $ e2) =
walther@59700
   340
    (case scan_dn2 cc (ist |> path_down [L, R]) e1 of
walther@59712
   341
	    Term_Val2 v => scan_dn2 cc (ist |> path_down [R] |> set_act v) e2
walther@59722
   342
    | (*Accept_Tac2*) goback => goback)
walther@59689
   343
walther@59711
   344
  | scan_dn2 cc ist (Const ("HOL.Let"(*1*), _) $ e $ (Abs (i, T, b))) =
walther@59700
   345
     (case scan_dn2 cc (ist |> path_down [L, R]) e of
walther@59712
   346
       Term_Val2 res => scan_dn2 cc (ist |> path_down [R, D] |> upd_env'' (Free (i, T), res)) b
walther@59722
   347
    | (*Accept_Tac2*) goback => goback)
walther@59678
   348
walther@59711
   349
  | scan_dn2 (cc as (_, ctxt)) (ist as {eval, act_arg, ...}) (Const ("Tactical.While"(*1*), _) $ c $ e $ a) =
walther@59722
   350
    if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (ist |> get_act_env |> Env.update' a) c)
walther@59700
   351
    then scan_dn2 cc (ist |> path_down_form ([L, R], a)) e
walther@59712
   352
    else Term_Val2 act_arg
walther@59711
   353
  | scan_dn2 (cc as (_, ctxt)) (ist as {eval, act_arg, ...}) (Const ("Tactical.While"(*2*), _) $ c $ e) =
walther@59722
   354
    if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
walther@59700
   355
    then scan_dn2 cc (ist |> path_down [R]) e
walther@59712
   356
    else Term_Val2 act_arg
walther@59678
   357
walther@59700
   358
  |scan_dn2 cc ist (Const ("Tactical.Or"(*1*), _) $e1 $ e2 $ a) =
walther@59700
   359
    (case scan_dn2 cc (ist |> path_down_form ([L, L, R], a)) e1 of
walther@59718
   360
	    Accept_Tac2 lme => Accept_Tac2 lme
walther@59700
   361
    | _ => scan_dn2 cc (ist |> path_down_form ([L, R], a)) e2)
walther@59700
   362
  | scan_dn2 cc ist (Const ("Tactical.Or"(*2*), _) $e1 $ e2) =
walther@59700
   363
    (case scan_dn2 cc (ist |> path_down [L, R]) e1 of
walther@59718
   364
	    Accept_Tac2 lme => Accept_Tac2 lme
walther@59700
   365
    | _ => scan_dn2 cc (ist |> path_down [R]) e2)
walther@59689
   366
walther@59700
   367
  |  scan_dn2 (cc as (_, ctxt)) (ist as {eval, ...}) (Const ("Tactical.If"(*1*), _) $ c $ e1 $ e2) =
walther@59722
   368
    if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c)
walther@59700
   369
    then scan_dn2 cc (ist |> path_down [L, R]) e1
walther@59700
   370
    else scan_dn2 cc (ist |> path_down [R]) e2
walther@59678
   371
walther@59715
   372
  | scan_dn2 ((pt, p), ctxt) (ist as {eval, ...}) t =
walther@59716
   373
    if Tactical.contained_in t then raise TERM ("scan_dn2 expects Prog_Tac or Prog_Expr", [t])
walther@59716
   374
    else
walther@59718
   375
      case Lucin.interpret_leaf "next  " ctxt eval (get_subst ist) t of
walther@59721
   376
  	    (Program.Expr s, _) => Term_Val2 s
walther@59721
   377
      | (Program.Tac stac, a') =>
walther@59716
   378
  	    let
walther@59722
   379
  	      val (m, m') = Lucin.stac2tac_ pt (Proof_Context.theory_of ctxt) stac
walther@59716
   380
        in
walther@59716
   381
          case m of (*TODO?: make applicable_in..Subproblem analogous to other tacs ?refine problem?*)
walther@59728
   382
    	      Tactic.Subproblem _ =>
walther@59728
   383
    	        Accept_Tac2 (m', ist |> set_subst_reset (a', Tactic.result m'), ctxt)
walther@59716
   384
    	    | _ =>
walther@59716
   385
            (case Applicable.applicable_in p pt m of
walther@59735
   386
    		      Applicable.Appl m' => Accept_Tac2 (m',
walther@59728
   387
    		        ist |> set_subst_reset (a', Tactic.result m'), Tactic.insert_assumptions m' ctxt)
walther@59716
   388
    		    | _ => Reject_Tac2)
walther@59716
   389
  	    end
wneuper@59554
   390
walther@59712
   391
    (*makes Reject_Tac2 to Term_Val2*)
walther@59720
   392
fun go_scan_up2 (pcc as (sc, _)) (ist as {path, act_arg, finish, ...}) = 
walther@59720
   393
    if 1 < length path
walther@59720
   394
    then 
walther@59720
   395
      scan_up2 pcc (ist |> path_up) (go_up path sc)
walther@59720
   396
    else (*interpreted to end*)
walther@59720
   397
      if finish = Skip_ then Term_Val2 act_arg else Reject_Tac2
walther@59720
   398
and scan_up2 pcc ist (Const ("Tactical.Try"(*1*), _) $ _ $ _) = go_scan_up2 pcc (ist |> set_appy Skip_)
walther@59700
   399
  | scan_up2 pcc ist (Const ("Tactical.Try"(*2*), _) $ _) = go_scan_up2 pcc (ist |> set_appy Skip_)
walther@59689
   400
walther@59711
   401
  | scan_up2 (pcc as (_, cc)) ist (Const ("Tactical.Repeat"(*1*), _) $ e $ _) =
walther@59700
   402
    (case scan_dn2 cc (ist |> path_down [L, R]) e of (* no appy_: there was already a stac below *)
walther@59718
   403
      Accept_Tac2 lr => Accept_Tac2 lr
walther@59712
   404
    | Reject_Tac2 =>  go_scan_up2 pcc (ist |> set_appy Skip_)
walther@59712
   405
    | Term_Val2 v =>  go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_))
walther@59701
   406
    (*no appy_: there was already a stac below*)
walther@59722
   407
  | scan_up2 (pcc as (_, cc)) ist (Const ("Tactical.Repeat"(*2*), _) $ e) =
walther@59700
   408
    (case scan_dn2 cc (ist |> path_down [R]) e of
walther@59718
   409
      Accept_Tac2 lr => Accept_Tac2 lr
walther@59712
   410
    | Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
walther@59712
   411
    | Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_))
walther@59689
   412
walther@59700
   413
  | scan_up2 pcc ist (Const ("Tactical.Chain"(*1*), _) $ _ $ _ $ _) = go_scan_up2 pcc ist
walther@59700
   414
  | scan_up2 pcc ist (Const ("Tactical.Chain"(*2*), _) $ _ $ _) = go_scan_up2 pcc ist
walther@59711
   415
  | scan_up2 (pcc as (sc, cc)) (ist as {finish, ...}) (Const ("Tactical.Chain"(*3*), _) $ _) =
walther@59689
   416
    if finish = Napp_
walther@59700
   417
    then go_scan_up2 pcc (ist |> path_up)
walther@59689
   418
    else (*Skip_*)
walther@59689
   419
      let 
walther@59689
   420
        val e2 = check_Seq_up ist sc
walther@59689
   421
      in
walther@59700
   422
        case scan_dn2 cc (ist |> path_up_down [R]) e2 of
walther@59718
   423
          Accept_Tac2 lr => Accept_Tac2 lr
walther@59712
   424
        | Reject_Tac2 => go_scan_up2 pcc (ist |> path_up)
walther@59712
   425
        | Term_Val2 v => go_scan_up2 pcc (ist |> path_up |> set_act v |> set_appy Skip_)
walther@59689
   426
      end
walther@59690
   427
walther@59711
   428
  | scan_up2 (pcc as (sc, cc)) (ist as {finish, ...}) (Const ("HOL.Let"(*1*), _) $ _) =
walther@59685
   429
    if finish = Napp_
walther@59700
   430
    then go_scan_up2 pcc (ist |> path_up)
walther@59671
   431
    else (*Skip_*)
walther@59671
   432
	    let
walther@59685
   433
        val (i, body) = check_Let_up ist sc
walther@59671
   434
      in
walther@59700
   435
        case scan_dn2 cc (ist |> path_up_down [R, D] |> upd_env i) body of
walther@59718
   436
	        Accept_Tac2 lre => Accept_Tac2 lre
walther@59712
   437
	      | Reject_Tac2 => go_scan_up2 pcc (ist |> path_up)
walther@59712
   438
	      | Term_Val2 v => go_scan_up2 pcc (ist |> path_up |> set_act v |> set_appy Skip_)
walther@59671
   439
	    end
walther@59700
   440
  | scan_up2 pcc ist (Abs _(*2*)) =  go_scan_up2 pcc ist
walther@59700
   441
  | scan_up2 pcc ist (Const ("HOL.Let"(*3*),_) $ _ $ (Abs _)) =
walther@59700
   442
    go_scan_up2 pcc ist
walther@59678
   443
walther@59712
   444
    (*no appy_: never causes Reject_Tac2 -> Helpless*)
walther@59711
   445
  | scan_up2 (pcc as (_, cc as (_, ctxt)))  (ist as {eval, ...}) (Const ("Tactical.While"(*1*), _) $ c $ e $ _) = 
walther@59722
   446
    if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c) 
walther@59671
   447
    then
walther@59700
   448
      case scan_dn2 cc (ist |> path_down [L, R]) e of
walther@59718
   449
  	     Accept_Tac2 lr => Accept_Tac2 lr
walther@59712
   450
  	  | Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
walther@59712
   451
  	  | Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_)
walther@59671
   452
    else
walther@59700
   453
      go_scan_up2 pcc (ist |> set_appy Skip_)
walther@59712
   454
    (*no appy_: never causes Reject_Tac2 - Helpless*)
walther@59711
   455
  | scan_up2  (pcc as (_, cc as (_, ctxt))) (ist as {eval, ...}) (Const ("Tactical.While"(*2*), _) $ c $ e) = 
walther@59722
   456
    if Rewrite.eval_true_ (Proof_Context.theory_of ctxt) eval (subst_atomic (Env.update_opt' (get_subst ist)) c) 
walther@59671
   457
    then
walther@59700
   458
      case scan_dn2 cc (ist |> path_down [R]) e of
walther@59718
   459
  	    Accept_Tac2 lr => Accept_Tac2 lr
walther@59712
   460
  	  | Reject_Tac2 => go_scan_up2 pcc (ist |> set_appy Skip_)
walther@59712
   461
  	  | Term_Val2 v => go_scan_up2 pcc (ist |> set_act v |> set_appy Skip_)
walther@59671
   462
    else
walther@59700
   463
      go_scan_up2 pcc (ist |> set_appy Skip_)
walther@59678
   464
walther@59700
   465
  | scan_up2 pcc ist (Const ("Tactical.Or"(*1*), _) $ _ $ _ $ _) = go_scan_up2 pcc ist
walther@59700
   466
  | scan_up2 pcc ist (Const ("Tactical.Or"(*2*), _) $ _ $ _) = go_scan_up2 pcc ist
walther@59700
   467
  | scan_up2 pcc ist (Const ("Tactical.Or"(*3*), _) $ _ ) = go_scan_up2 pcc ist
walther@59678
   468
walther@59700
   469
  | scan_up2 pcc ist (Const ("Tactical.If"(*1*), _) $ _ $ _ $ _) = go_scan_up2 pcc ist
walther@59678
   470
walther@59691
   471
  | scan_up2 _ _ t = error ("scan_up2 not impl for " ^ Rule.term2str t)
wneuper@59554
   472
walther@59731
   473
(* scan program until an applicable tactic is found *)
walther@59700
   474
fun scan_to_tactic2 (prog, cc) (Istate.Pstate (ist as {path, ...})) =
walther@59699
   475
  if path = []
walther@59700
   476
  then scan_dn2 cc (trans_scan_down2 ist) (Program.body_of prog)
walther@59700
   477
  else go_scan_up2 (prog, cc) (trans_scan_up2 ist |> set_appy Skip_)
walther@59690
   478
| scan_to_tactic2 _ _ = raise ERROR "scan_to_tactic2: uncovered pattern";
wneuper@59565
   479
walther@59729
   480
(* decide for the next applicable Prog_Tac *)
walther@59743
   481
fun find_next_tactic (Rule.Prog prog) (ptp as(pt, (p, _))) (Istate.Pstate ist) ctxt =
walther@59722
   482
   (case scan_to_tactic2 (prog, (ptp, ctxt)) (Istate.Pstate ist) of
walther@59748
   483
      Accept_Tac2 (tac, ist, ctxt) =>
walther@59748
   484
        Next_Step (Istate.Pstate ist, Tactic.insert_assumptions tac ctxt, tac)
walther@59748
   485
    | Term_Val2 prog_result =>
walther@59675
   486
        (case par_pbl_det pt p of
walther@59748
   487
          (true, p', _) => 
walther@59748
   488
            let
walther@59748
   489
              val (_, pblID, _) = get_obj g_spec pt p';
walther@59748
   490
            in
walther@59748
   491
              End_Program (Istate.Pstate ist, Tactic.Check_Postcond' (pblID, (prog_result, [(*???*)])))
walther@59675
   492
            end
walther@59748
   493
        | _ => End_Program (Istate.Pstate ist, Tactic.End_Detail' (Rule.e_term,[])))
walther@59748
   494
    | Reject_Tac2 => Helpless)
walther@59743
   495
  | find_next_tactic _ _ is _ =
walther@59743
   496
    raise ERROR ("find_next_tactic: not impl for " ^ Istate.istate2str is);
wneuper@59554
   497
walther@59701
   498
walther@59701
   499
(*** locate an input formula in the program ***)
wneuper@59569
   500
wneuper@59562
   501
datatype input_formula_result =
walther@59747
   502
    Found_Step of Ctree.state * Istate.T * Proof.context
wneuper@59562
   503
  | Not_Derivable of Chead.calcstate'
wneuper@59562
   504
walther@59751
   505
(* FIXME.WN050821 compare fun solve ... fun by_tactic *)
walther@59751
   506
fun by_tactic (Tactic.Apply_Method' (mI, _, _, _)) (_, ctxt) (pt, pos as (p, _)) =
wneuper@59562
   507
    let
wneuper@59562
   508
      val {ppc, ...} = Specify.get_met mI;
wneuper@59562
   509
      val (itms, oris, probl) = case get_obj I pt p of
wneuper@59562
   510
        PblObj {meth = itms, origin = (oris, _, _), probl, ...} => (itms, oris, probl)
walther@59751
   511
      | _ => error "by_tactic Apply_Method': uncovered case get_obj"
wneuper@59562
   512
      val itms = if itms <> [] then itms else Chead.complete_metitms oris probl [] ppc
wneuper@59562
   513
      val thy' = get_obj g_domID pt p;
wneuper@59562
   514
      val thy = Celem.assoc_thy thy';
walther@59677
   515
      val srls = Lucin.get_simplifier (pt, pos)
walther@59742
   516
      val itms = Specify.hack_until_review_Specify_1 mI itms
walther@59742
   517
      val (is, env, ctxt, scr) = case Lucin.init_pstate srls ctxt itms mI of
walther@59742
   518
        (is as Istate.Pstate {env, ...}, ctxt, scr) => (is, env, ctxt, scr)
walther@59751
   519
      | _ => error "by_tactic Apply_Method': uncovered case init_pstate"
wneuper@59555
   520
     val ini = Lucin.init_form thy scr env;
wneuper@59555
   521
   in 
wneuper@59555
   522
     case ini of
wneuper@59555
   523
       SOME t =>
wneuper@59555
   524
       let
wneuper@59555
   525
         val pos = ((lev_on o lev_dn) p, Frm)
wneuper@59571
   526
	       val tac_ = Tactic.Apply_Method' (mI, SOME t, is, ctxt);
wneuper@59555
   527
	       val (pos, c, _, pt) = Generate.generate1 thy tac_ (is, ctxt) pos pt (* implicit Take *)
wneuper@59555
   528
       in
wneuper@59571
   529
        ([(Tactic.Apply_Method mI, tac_, (pos, (is, ctxt)))], c, (pt, pos))
wneuper@59555
   530
       end
wneuper@59555
   531
     | NONE =>
wneuper@59555
   532
       let
wneuper@59555
   533
         val pt = update_env pt (fst pos) (SOME (is, ctxt))
wneuper@59562
   534
	       val (tacis, c, ptp) = do_solve_step (pt, pos)
walther@59658
   535
       in (tacis @ [(Tactic.Apply_Method mI,
walther@59658
   536
            Tactic.Apply_Method' (mI, NONE, Istate.e_istate, ctxt), (pos, (is, ctxt)))], c, ptp)
wneuper@59555
   537
       end
wneuper@59555
   538
    end
walther@59751
   539
  | by_tactic (Tactic.Check_Postcond' (pI, (prog_res, _))) _ (pt, (p, p_))  =
wneuper@59555
   540
    let
wneuper@59555
   541
      val pp = par_pblobj pt p
walther@59746
   542
      val thy = Celem.assoc_thy (get_obj g_domID pt pp);
walther@59723
   543
      val (pst, ctxt) = case get_loc pt (p, p_) of (Istate.Pstate pst, ctxt) => (pst, ctxt)
walther@59751
   544
      | _ => error "by_tactic Check_Postcond': uncovered case get_loc"
walther@59746
   545
      val asm = (case get_obj g_tac pt p of (*collects and instantiates asms*)
walther@59746
   546
        Tactic.Check_elementwise _ => (snd o (get_obj g_result pt)) p
walther@59746
   547
      | _ => get_assumptions_ pt (p, p_))
walther@59746
   548
	    val tac = Tactic.Check_Postcond' (pI, (prog_res, asm))
wneuper@59555
   549
    in
walther@59746
   550
      if pp = []
wneuper@59555
   551
      then 
wneuper@59555
   552
	      let
walther@59732
   553
          val is = Istate.Pstate (pst |> Istate.set_act prog_res |> Istate.set_appy Istate.Skip_)
walther@59732
   554
	        val ((p, p_), ps, _, pt) = Generate.generate1 thy tac (is, ctxt) (pp, Res) pt;
walther@59732
   555
	      in ([(Tactic.Check_Postcond pI, tac, ((pp, Res), (is, ctxt)))], ps, (pt, (p, p_))) end
wneuper@59555
   556
      else
walther@59675
   557
        let (*resume script of parent PblObj, transfer value of subpbl-script*)
walther@59746
   558
          val thy = Celem.assoc_thy (get_obj g_domID pt (par_pblobj pt (lev_up p)));
walther@59676
   559
walther@59676
   560
          val (pst', ctxt') = case get_loc pt (pp, Frm) of
walther@59676
   561
            (Istate.Pstate pst', ctxt') => (pst', ctxt')
walther@59751
   562
          | _ => error "by_tactic Check_Postcond' script of parpbl: uncovered case get_loc"
walther@59732
   563
	        val ctxt'' = ContextC.from_subpbl_to_caller ctxt prog_res ctxt'
walther@59732
   564
	        val is = Istate.Pstate (pst' |> Istate.set_act prog_res |> Istate.set_appy Istate.Skip_)
walther@59732
   565
          val ((p, p_), ps, _, pt) = Generate.generate1 thy tac (is, ctxt'') (pp, Res) pt;
walther@59732
   566
        in ([(Tactic.Check_Postcond pI, tac, ((pp, Res), (is, ctxt'')))], ps, (pt, (p, p_))) end
wneuper@59555
   567
    end
walther@59751
   568
  | by_tactic (Tactic.End_Proof'') _ ptp = ([], [], ptp)
walther@59751
   569
  | by_tactic tac_ is (pt, pos) =
wneuper@59555
   570
    let
wneuper@59555
   571
      val pos = case pos of
walther@59731
   572
 		   (p, Met) => ((lev_on o lev_dn) p, Frm) (* begin program        *)
walther@59731
   573
 		  | (p, Res) => (lev_on p, Res)           (* somewhere in program *)
wneuper@59555
   574
 		  | _ => pos
wneuper@59592
   575
 	    val (pos', c, _, pt) = Generate.generate1 (Celem.assoc_thy "Isac_Knowledge") tac_ is pos pt;
wneuper@59555
   576
    in
walther@59704
   577
      ([(Tactic.input_from_T tac_, tac_, (pos, is))], c, (pt, pos'))
wneuper@59555
   578
    end
walther@59751
   579
(*find_next_tactic from program, by_tactic will update the ctree*)
walther@59746
   580
and do_solve_step (ptp as (pt, pos as (p, p_))) =
wneuper@59555
   581
    if Celem.e_metID = get_obj g_metID pt (par_pblobj pt p)
wneuper@59555
   582
    then ([], [], (pt, (p, p_)))
wneuper@59555
   583
    else 
wneuper@59555
   584
      let 
wneuper@59555
   585
        val thy' = get_obj g_domID pt (par_pblobj pt p);
walther@59723
   586
	      val (_, (ist, ctxt), sc) = Lucin.from_pblobj_or_detail' thy' (p,p_) pt;
walther@59745
   587
      in
walther@59745
   588
        case find_next_tactic sc (pt, pos) ist ctxt of
walther@59745
   589
           Next_Step (ist, ctxt, tac) =>
walther@59751
   590
             by_tactic tac (ist, Tactic.insert_assumptions tac ctxt) ptp
walther@59745
   591
         | End_Program (ist, tac) =>
walther@59745
   592
             (case tac of
walther@59745
   593
               Tactic.End_Detail' res =>
walther@59745
   594
                 ([(Tactic.End_Detail, 
walther@59745
   595
                   Tactic.End_Detail' res, (pos, (ist, ctxt)))], [], ptp)
walther@59751
   596
             | _ => by_tactic tac (ist, ctxt) ptp)
walther@59745
   597
         | Helpless => Chead.e_calcstate'
walther@59745
   598
      end;
walther@59686
   599
walther@59701
   600
(*
walther@59701
   601
  compare inform with ctree.form at current pos by nrls;
walther@59701
   602
  if found, embed the derivation generated during comparison
walther@59701
   603
  if not, let the mat-engine compute the next ctree.form.
walther@59701
   604
walther@59701
   605
  Code's structure is copied from complete_solve
walther@59701
   606
  CAUTION: tacis in returned calcstate' do NOT construct resulting ptp --
walther@59701
   607
           all_modspec etc. has to be inserted at Subproblem'
walther@59701
   608
*)
wneuper@59555
   609
fun compare_step ((tacis, c, ptp as (pt, pos as (p,p_))): Chead.calcstate') ifo =
wneuper@59555
   610
  let
wneuper@59555
   611
    val fo =
wneuper@59555
   612
      case p_ of
walther@59694
   613
        Pos.Frm => Ctree.get_obj Ctree.g_form pt p
walther@59694
   614
			| Pos.Res => (fst o (Ctree.get_obj Ctree.g_result pt)) p
wneuper@59555
   615
			| _ => Rule.e_term (*on PblObj is fo <> ifo*);
wneuper@59555
   616
	  val {nrls, ...} = Specify.get_met (Ctree.get_obj Ctree.g_metID pt (Ctree.par_pblobj pt p))
wneuper@59555
   617
	  val {rew_ord, erls, rules, ...} = Rule.rep_rls nrls
wneuper@59555
   618
	  val (found, der) = Inform.concat_deriv rew_ord erls rules fo ifo; (*<---------------*)
wneuper@59555
   619
  in
wneuper@59555
   620
    if found
wneuper@59555
   621
    then
wneuper@59555
   622
       let
wneuper@59555
   623
         val tacis' = map (Inform.mk_tacis rew_ord erls) der;
wneuper@59555
   624
		     val (c', ptp) = Generate.embed_deriv tacis' ptp;
wneuper@59555
   625
	     in ("ok", (tacis (*@ tacis'?WN050408*), c @ c', ptp)) end
wneuper@59555
   626
     else 
walther@59694
   627
	     if pos = ([], Pos.Res) (*TODO: we should stop earlier with trying subproblems *)
wneuper@59555
   628
	     then ("no derivation found", (tacis, c, ptp): Chead.calcstate') 
wneuper@59555
   629
	     else
wneuper@59555
   630
         let
wneuper@59562
   631
           val cs' as (tacis, c', ptp) = do_solve_step ptp; (*<---------------------*)
wneuper@59555
   632
		       val (tacis, c'', ptp) = case tacis of
wneuper@59571
   633
			       ((Tactic.Subproblem _, _, _)::_) => 
wneuper@59555
   634
			         let
wneuper@59555
   635
                 val ptp as (pt, (p,_)) = Chead.all_modspec ptp (*<--------------------*)
wneuper@59555
   636
				         val mI = Ctree.get_obj Ctree.g_metID pt p
wneuper@59555
   637
			         in
walther@59751
   638
			           by_tactic (Tactic.Apply_Method' (mI, NONE, Istate.e_istate, ContextC.e_ctxt)) (Istate.e_istate, ContextC.e_ctxt) ptp
wneuper@59555
   639
               end
wneuper@59555
   640
			     | _ => cs';
wneuper@59555
   641
		     in compare_step (tacis, c @ c' @ c'', ptp) ifo end
wneuper@59555
   642
  end
wneuper@59555
   643
walther@59701
   644
(*
walther@59701
   645
  handle a user-input formula, which may be a CAS-command, too.
walther@59701
   646
 * CAS-command: create a calchead, and do 1 step
walther@59701
   647
 * formula, which is no CAS-command:
wneuper@59556
   648
   compare iform with calc-tree.form at pos by equ_nrls and all subsequent pos;
walther@59701
   649
   collect all the Prog_Tac applied by the way; ...???TODO?
walther@59701
   650
   If "no derivation found" then check_error_patterns.
walther@59701
   651
   ALTERNATIVE: check_error_patterns _within_ compare_step: seems too expensive
walther@59701
   652
*)
wneuper@59562
   653
(*                       vvvv           vvvvvv vvvv    NEW args for compare_step *)
walther@59658
   654
fun locate_input_formula (Rule.Prog _)  ((pt, pos) : Ctree.state) (_ : Istate.T) (_ : Proof.context) tm =
walther@59658
   655
     let                                                          
walther@59658
   656
   		val pos_pred = Ctree.lev_back' pos (*f_pred ---"step pos cs"---> f_succ in appendFormula*)
walther@59658
   657
   		val _(*f_pred*) = Ctree.get_curr_formula (pt, pos_pred)
walther@59658
   658
     in
walther@59658
   659
       (*TODO: use prog, istate, ctxt in compare_step ...*)
walther@59658
   660
   		case compare_step ([], [], (pt, pos_pred)) tm of
walther@59658
   661
   		  ("no derivation found", calcstate') => Not_Derivable calcstate'
walther@59658
   662
       | ("ok", (_, _, cstate as (pt', pos'))) => 
walther@59747
   663
           Found_Step (cstate, get_istate pt' pos', get_ctxt pt' pos')
walther@59658
   664
       | _ => raise ERROR "compare_step: uncovered case"
walther@59658
   665
     end
walther@59658
   666
  | locate_input_formula _ _ _ _ _ = error ""
wneuper@59556
   667
walther@59684
   668
(**)end(**)