src/Tools/isac/ProgLang/Prog_Tac.thy
author wenzelm
Mon, 21 Jun 2021 15:36:09 +0200
changeset 60309 70a1d102660d
parent 60278 343efa173023
child 60335 7701598a2182
permissions -rw-r--r--
more antiquotations for Isabelle/HOL consts/types, without change of semantics;
wneuper@59601
     1
(* Title:  tactics, tacticals etc. for scripts
wneuper@59601
     2
   Author: Walther Neuper 000224
wneuper@59601
     3
   (c) due to copyright terms
wneuper@59601
     4
 *)
wneuper@59601
     5
walther@59603
     6
theory Prog_Tac
walther@59717
     7
  imports Program
walther@59603
     8
begin
wneuper@59601
     9
walther@59619
    10
text \<open>Abstract:
walther@59619
    11
  Specific constants for tactics in programs, which each create a step in a calculation
walther@59619
    12
  as a side effect.
walther@59619
    13
  These program-tactics are related to Tactic.input for use in calculations and
walther@59619
    14
  Tactic.T for internal use by lucas-interpretation.
walther@59619
    15
\<close>
walther@59619
    16
wneuper@59601
    17
subsection \<open>arguments of tactic SubProblem\<close>
wneuper@59601
    18
wneuper@59601
    19
typedecl
wneuper@59601
    20
  arg
wneuper@59601
    21
wneuper@59601
    22
consts
wneuper@59601
    23
  REAL        :: "real => arg"
wneuper@59601
    24
  REAL_LIST   :: "(real list) => arg"
wneuper@59601
    25
  REAL_SET    :: "(real set) => arg"
wneuper@59601
    26
  BOOL        :: "bool => arg"
wneuper@59601
    27
  BOOL_LIST   :: "(bool list) => arg"
wneuper@59601
    28
  REAL_REAL   :: "(real => real) => arg"
wneuper@59601
    29
  STRING      :: "(char list) => arg"
wneuper@59601
    30
  STRING_LIST :: "(char list list) => arg"
wneuper@59601
    31
wneuper@59601
    32
subsection \<open>tactics in programs\<close>
wneuper@59601
    33
text \<open>
wneuper@59601
    34
  Note: the items below MUST ALL be recorded in xxx TODO
wneuper@59601
    35
\<close>
wneuper@59601
    36
consts
walther@59634
    37
  Calculate    :: "[char list, 'a] => 'a"
walther@59635
    38
  Rewrite      :: "[char list, 'a] => 'a"
walther@60278
    39
  Rewrite_Inst:: "[(char list * 'b) list, char list, 'a] => 'a"
walther@59637
    40
			               ("(Rewrite'_Inst (_ _))" 11) (*without last argument ^^ for #>*)
walther@60278
    41
  Rewrite_Set :: "[char list, 'a] => 'a" ("(Rewrite'_Set (_))" 11)
walther@60278
    42
  Rewrite_Set_Inst
walther@59636
    43
               :: "[((char list) * 'b) list, char list, 'a] => 'a"
walther@59637
    44
		                 ("(Rewrite'_Set'_Inst (_ _))" 11) (*without last argument ^^ for #>*)
walther@60278
    45
  Or_to_List :: "bool => 'a list"  ("Or'_to'_List (_)" 11)
walther@59634
    46
  SubProblem   :: "[char list * char list list * char list list, arg list] => 'a"
walther@59634
    47
  Substitute   :: "[bool list, 'a] => 'a"
walther@59634
    48
  Take         :: "'a => 'a"
walther@59634
    49
walther@59635
    50
  (* legacy.. *)
walther@60278
    51
  Check_elementwise :: (* TODO: is idle, retained for test purposes in Minisubpbl *)
wneuper@59601
    52
		  "['a list, 'b set] => 'a list" ("Check'_elementwise (_ _)" 11)
wneuper@59601
    53
  Assumptions  :: bool  (* TODO: remove with making ^^^ idle *)
walther@59634
    54
wneuper@59601
    55
walther@59716
    56
subsection \<open>ML code for Prog_Tac\<close>
wneuper@59601
    57
ML \<open>
wneuper@59601
    58
signature PROGAM_TACTIC =
wneuper@59601
    59
sig
walther@59985
    60
  val dest_spec : term -> References_Def.T
walther@59848
    61
  val get_first_argument : term -> term option (*TODO rename get_first_argument*)
walther@59800
    62
  val eval_leaf: Env.T -> term option -> term -> term -> Program.leaf * term option
walther@59716
    63
  val is: term -> bool
wneuper@59601
    64
end 
wneuper@59601
    65
\<close> ML \<open>
wneuper@59601
    66
(**)
wneuper@59601
    67
structure Prog_Tac(**): PROGAM_TACTIC(**) =
wneuper@59601
    68
struct
wneuper@59601
    69
(**)
wneuper@59601
    70
wenzelm@60309
    71
fun dest_spec (Const (\<^const_name>\<open>Pair\<close>, _) $ d $ (Const (\<^const_name>\<open>Pair\<close>, _) $ p $ m)) =
walther@59618
    72
    (d |> HOLogic.dest_string, 
walther@59618
    73
     p |> HOLogic.dest_list |> map HOLogic.dest_string,
walther@59985
    74
     m |> HOLogic.dest_list |> map HOLogic.dest_string) : References_Def.T
walther@59618
    75
  | dest_spec t = raise TERM ("dest_spec: called with ", [t])
walther@59618
    76
walther@59845
    77
(* get argument of first Prog_Tac in a progam for implicit_take *)
walther@59848
    78
fun get_first_argument (_ $ body) =
wneuper@59601
    79
  let
walther@59637
    80
    (* entries occur twice, for form curried by #> or non-curried *)
walther@59848
    81
    fun get_t (Const ("Tactical.Chain",_) $ e1 $ e2) a = 
walther@59848
    82
    	  (case get_t e1 a of NONE => get_t e2 a | la => la)
walther@59848
    83
      | get_t (Const ("Tactical.Chain",_) $ e1 $ e2 $ a) _ = 
walther@59848
    84
    	  (case get_t e1 a of NONE => get_t e2 a | la => la)
walther@59848
    85
      | get_t (Const ("Tactical.Try",_) $ e) a = get_t e a
walther@59848
    86
      | get_t (Const ("Tactical.Try",_) $ e $ a) _ = get_t e a
walther@59848
    87
      | get_t (Const ("Tactical.Repeat",_) $ e) a = get_t e a
walther@59848
    88
      | get_t (Const ("Tactical.Repeat",_) $ e $ a) _ = get_t e a
walther@59848
    89
      | get_t (Const ("Tactical.Or",_) $e1 $ e2) a =
walther@59848
    90
    	  (case get_t e1 a of NONE => get_t e2 a | la => la)
walther@59848
    91
      | get_t (Const ("Tactical.Or",_) $e1 $ e2 $ a) _ =
walther@59848
    92
    	  (case get_t e1 a of NONE => get_t e2 a | la => la)
walther@59848
    93
      | get_t (Const ("Tactical.While",_) $ _ $ e) a = get_t e a
walther@59848
    94
      | get_t (Const ("Tactical.While",_) $ _ $ e $ a) _ = get_t e a
walther@59848
    95
      | get_t (Const ("Tactical.Letpar",_) $ e1 $ Abs (_, _, e2)) a = 
walther@59848
    96
    	  (case get_t e1 a of NONE => get_t e2 a | la => la)
wenzelm@60309
    97
      | get_t (Const (\<^const_name>\<open>Let\<close>,_) $ e1 $ Abs (_, _, _)) a =
walther@59848
    98
    	  get_t e1 a (* don't go deeper without evaluation *)
walther@59848
    99
      | get_t (Const ("If", _) $ _ $ _ $ _) _ = NONE
wneuper@59601
   100
    
walther@59848
   101
      | get_t (Const ("Prog_Tac.Rewrite",_) $ _ $ a) _ = SOME a
walther@59848
   102
      | get_t (Const ("Prog_Tac.Rewrite",_) $ _ ) a = SOME a
walther@60278
   103
      | get_t (Const ("Prog_Tac.Rewrite_Inst",_) $ _ $ _ $ a) _ = SOME a
walther@60278
   104
      | get_t (Const ("Prog_Tac.Rewrite_Inst",_) $ _ $ _ )    a = SOME a
walther@60278
   105
      | get_t (Const ("Prog_Tac.Rewrite_Set",_) $ _ $ a) _ = SOME a
walther@60278
   106
      | get_t (Const ("Prog_Tac.Rewrite_Set",_) $ _ )    a = SOME a
walther@60278
   107
      | get_t (Const ("Prog_Tac.Rewrite_Set_Inst",_) $ _ $ _ $a)_ =SOME a
walther@60278
   108
      | get_t (Const ("Prog_Tac.Rewrite_Set_Inst",_) $ _ $ _ )  a =SOME a
walther@59848
   109
      | get_t (Const ("Prog_Tac.Calculate",_) $ _ $ a) _ = SOME a
walther@59848
   110
      | get_t (Const ("Prog_Tac.Calculate",_) $ _ )    a = SOME a
walther@59848
   111
      | get_t (Const ("Prog_Tac.Substitute",_) $ _ $ a) _ = SOME a
walther@59848
   112
      | get_t (Const ("Prog_Tac.Substitute",_) $ _ )    a = SOME a
wneuper@59601
   113
    
walther@59848
   114
      | get_t (Const ("Prog_Tac.SubProblem",_) $ _ $ _) _ = NONE
wneuper@59601
   115
walther@59848
   116
      | get_t _ _ = ((*tracing ("### get_t yac: list-expr "^(term2str x));*) NONE)
walther@59861
   117
    in get_t body TermC.empty end
walther@59962
   118
  | get_first_argument t = raise ERROR ("get_first_argument: no fun-def. for " ^ UnparseC.term t);
wneuper@59601
   119
walther@59635
   120
(* substitute the Istate.T's environment to a leaf of the program
wneuper@59601
   121
   and attach the curried argument of a tactic, if any.
walther@59637
   122
CAUTION: (1) currying with #> requires 2 patterns for each tactic
wneuper@59601
   123
         (2) the non-curried version must return NONE for a 
walther@59800
   124
	       (3) non-matching patterns become a Prog_Expr by fall-through.
wneuper@59601
   125
WN060906 quick and dirty fix: due to (2) a is returned, too *)
walther@59718
   126
fun eval_leaf E _ _ (t as (Const ("Prog_Tac.Rewrite"(*1*), _) $ _ $ _)) =
walther@59729
   127
    (Program.Tac (subst_atomic E t), NONE)
walther@59718
   128
  | eval_leaf E a v (t as (Const ("Prog_Tac.Rewrite"(*2*), _) $ _)) =
walther@59729
   129
    (Program.Tac (
walther@59800
   130
      case a of SOME a' => (subst_atomic E (t $ a'))          
walther@59729
   131
		          | NONE => ((subst_atomic E t) $ v)),
walther@59729
   132
    a)
walther@60278
   133
  | eval_leaf E _ _ (t as (Const ("Prog_Tac.Rewrite_Inst"(*1*), _) $ _ $ _ $ _)) =
walther@59729
   134
    (Program.Tac (subst_atomic E t), NONE)
walther@60278
   135
  | eval_leaf E a v (t as (Const ("Prog_Tac.Rewrite_Inst"(*2*), _) $ _ $ _)) =
walther@59729
   136
    (Program.Tac (
walther@59717
   137
      case a of SOME a' => subst_atomic E (t $ a')
walther@59729
   138
	            | NONE => ((subst_atomic E t) $ v)),
walther@59729
   139
    a)
walther@60278
   140
  | eval_leaf E _ _ (t as (Const ("Prog_Tac.Rewrite_Set"(*1*), _) $ _ $ _)) =
walther@59729
   141
    (Program.Tac (subst_atomic E t), NONE)
walther@60278
   142
  | eval_leaf E a v (t as (Const ("Prog_Tac.Rewrite_Set"(*2*), _) $ _)) =
walther@59729
   143
    (Program.Tac (
walther@59717
   144
      case a of SOME a' => subst_atomic E (t $ a')
walther@59729
   145
	            | NONE => ((subst_atomic E t) $ v)),
walther@59729
   146
    a)
walther@60278
   147
  | eval_leaf E _ _ (t as (Const ("Prog_Tac.Rewrite_Set_Inst"(*1*), _) $ _ $ _ $ _)) =
walther@59729
   148
    (Program.Tac (subst_atomic E t), NONE)
walther@60278
   149
  | eval_leaf E a v (t as (Const ("Prog_Tac.Rewrite_Set_Inst"(*2*), _) $ _ $ _)) =
walther@59729
   150
    (Program.Tac (
walther@59717
   151
      case a of SOME a' => subst_atomic E (t $ a')
walther@59729
   152
	            | NONE => ((subst_atomic E t) $ v)),
walther@59729
   153
    a)
walther@59718
   154
  | eval_leaf E _ _ (t as (Const ("Prog_Tac.Calculate"(*1*), _) $ _ $ _)) =
walther@59729
   155
    (Program.Tac (subst_atomic E t), NONE)
walther@59718
   156
  | eval_leaf E a v (t as (Const ("Prog_Tac.Calculate"(*2*), _) $ _)) =
walther@59729
   157
    (Program.Tac (
walther@59717
   158
      case a of SOME a' => subst_atomic E (t $ a')
walther@59729
   159
	            | NONE => ((subst_atomic E t) $ v)),
walther@59729
   160
    a)
walther@60278
   161
  | eval_leaf E _ _ (t as (Const ("Prog_Tac.Check_elementwise"(*1*),_) $ _ $ _)) = 
walther@59729
   162
    (Program.Tac (subst_atomic E t), NONE)
walther@60278
   163
  | eval_leaf E a v (t as (Const ("Prog_Tac.Check_elementwise"(*2*), _) $ _)) = 
walther@59729
   164
    (Program.Tac (
walther@59717
   165
      case a of SOME a' => subst_atomic E (t $ a')
walther@59729
   166
		          | NONE => ((subst_atomic E t) $ v)),
walther@59729
   167
    a)
walther@60278
   168
  | eval_leaf E _ _ (t as (Const ("Prog_Tac.Or_to_List"(*1*), _) $ _)) = 
walther@59729
   169
    (Program.Tac (subst_atomic E t), NONE)
walther@60278
   170
  | eval_leaf E a v (t as (Const ("Prog_Tac.Or_to_List"(*2*), _))) = (*t $ v*)
walther@59729
   171
    (Program.Tac (
walther@59717
   172
      case a of SOME a' => subst_atomic E (t $ a')
walther@59729
   173
		          | NONE => ((subst_atomic E t) $ v)),
walther@59729
   174
    a)
walther@59718
   175
  | eval_leaf E _ _ (t as (Const ("Prog_Tac.SubProblem", _) $ _ $ _)) =
walther@59729
   176
    (Program.Tac (subst_atomic E t), NONE)
walther@59718
   177
  | eval_leaf E _ _ (t as (Const ("Prog_Tac.Take", _) $ _)) =
walther@59729
   178
    (Program.Tac (subst_atomic E t), NONE)
walther@59718
   179
  | eval_leaf E _ _ (t as (Const ("Prog_Tac.Substitute"(*1*), _) $ _ $ _)) =
walther@59729
   180
    (Program.Tac (subst_atomic E t), NONE)
walther@59718
   181
  | eval_leaf E a v (t as (Const ("Prog_Tac.Substitute"(*2*), _) $ _)) =
walther@59729
   182
    (Program.Tac (
walther@59717
   183
      case a of SOME a' => subst_atomic E (t $ a')
walther@59729
   184
		          | NONE => ((subst_atomic E t) $ v)),
walther@59729
   185
    a)
wneuper@59601
   186
  (*now all tactics are matched out and this leaf must be without a tactic*)
walther@59718
   187
  | eval_leaf E a v t = 
walther@59729
   188
    (Program.Expr (subst_atomic (case a of SOME a => Env.update E (a,v) | NONE => E) t), a);
wneuper@59601
   189
walther@59716
   190
walther@59716
   191
(* check if a term is a Prog_Tac *)
walther@59716
   192
walther@59716
   193
val SOME Calculate = TermC.parseNEW @{context} "Calculate";
walther@59716
   194
val SOME Rewrite = TermC.parseNEW @{context} "Rewrite";
walther@59716
   195
val SOME Rewrite_Inst = TermC.parseNEW @{context} "Rewrite'_Inst";
walther@59716
   196
val SOME Rewrite_Set = TermC.parseNEW @{context} "Rewrite'_Set";
walther@59716
   197
val SOME Rewrite_Set_Inst = TermC.parseNEW @{context} "Rewrite'_Set'_Inst";
walther@59716
   198
val SOME Or_to_List = TermC.parseNEW @{context} "Or'_to'_List";
walther@59716
   199
val SOME SubProblem = TermC.parseNEW @{context} "SubProblem";
walther@59716
   200
val SOME Substitute = TermC.parseNEW @{context} "Substitute";
walther@59716
   201
val SOME Take = TermC.parseNEW @{context} "Take";
walther@59716
   202
val SOME Check_elementwise = TermC.parseNEW @{context} "Check'_elementwise";
walther@59716
   203
val SOME Assumptions = TermC.parseNEW @{context} "Assumptions";
walther@59716
   204
walther@59716
   205
val all_Consts = [Calculate, Rewrite, Rewrite_Inst, Rewrite_Set, Rewrite_Set_Inst, Or_to_List,
walther@59716
   206
  SubProblem, Substitute, Take, Check_elementwise, Assumptions]
walther@59716
   207
walther@59716
   208
fun is t = TermC.contains_Const_typeless all_Consts t
wneuper@59601
   209
(**)end(**)
wneuper@59601
   210
\<close> ML \<open>
wneuper@59601
   211
\<close> 
wneuper@59601
   212
subsection \<open>TODO\<close>
wneuper@59601
   213
ML \<open>
wneuper@59601
   214
\<close> ML \<open>
wneuper@59601
   215
\<close> ML \<open>
wneuper@59601
   216
\<close> 
wneuper@59601
   217
end