src/Tools/isac/Interpret/error-pattern.sml
author wneuper <Walther.Neuper@jku.at>
Thu, 04 Aug 2022 12:48:37 +0200
changeset 60509 2e0b7ca391dc
parent 60500 59a3af532717
child 60523 8e4fe2fb6590
permissions -rw-r--r--
polish naming in Rewrite_Order
walther@59909
     1
(* title: Interpret/error-pattern.sml
neuper@37906
     2
   author: Walther Neuper
neuper@37906
     3
   0603
neuper@37906
     4
   (c) due to copyright terms
walther@59858
     5
walther@59906
     6
In case a term is input, which contains an "error pattern" (provided by a mathauthor),
walther@59906
     7
several "fill patterns" can be presented as help for the next step.)
neuper@37906
     8
*)
neuper@37906
     9
walther@59909
    10
signature ERROR_PATTERN =
wneuper@59262
    11
sig
walther@59909
    12
  type id = Error_Pattern_Def.id
walther@59909
    13
  type T = Error_Pattern_Def.T
walther@59909
    14
  val s_to_string : T list -> string
walther@59971
    15
  val empty: T
walther@59858
    16
walther@59909
    17
  type fill_in_id = Error_Pattern_Def.fill_in_id
walther@59909
    18
  type fill_in = Error_Pattern_Def.fill_in
walther@59971
    19
  val fill_in_empty: fill_in
walther@59971
    20
walther@59909
    21
  type record
walther@59909
    22
walther@59909
    23
  val from_store: Tactic.input -> Error_Pattern_Def.id list
walther@59909
    24
  val filled_exactly: Calc.T -> string -> string * Tactic.input
walther@59909
    25
  val check_for: term * term -> term * Env.T -> T list * Rule_Set.T -> id option
walther@59906
    26
walther@59909
    27
  val find_fill_patterns: Calc.T -> id -> record list
wenzelm@60223
    28
wenzelm@60223
    29
\<^isac_test>\<open>
walther@59910
    30
  val check_for': term * term -> subst -> id * term -> Rule_Set.T -> id option
Walther@60477
    31
  val fill_from_store: Subst.input option * Subst.T -> term -> id -> thm ->
walther@59909
    32
    record list
Walther@60477
    33
  val fill_form: Subst.input option * Subst.T -> thm * term -> id -> fill_in ->
walther@59909
    34
    record option
wenzelm@60223
    35
\<close>
walther@59909
    36
end
wneuper@59310
    37
walther@59822
    38
(**)
walther@59909
    39
structure Error_Pattern(**): ERROR_PATTERN(**) =
walther@59822
    40
struct
walther@59822
    41
(**)
neuper@37906
    42
walther@59909
    43
type id = Error_Pattern_Def.id;
walther@59909
    44
type T = Error_Pattern_Def.T;
walther@59909
    45
val s_to_string = Error_Pattern_Def.s_to_string;
walther@59971
    46
val empty = ("e_errpatID", [TermC.parse_patt @{theory} "?a = ?b"], [@{thm refl}])
walther@59858
    47
walther@59909
    48
type fill_in_id = Error_Pattern_Def.fill_in_id;
walther@59909
    49
type fill_in = Error_Pattern_Def.fill_in;
walther@59971
    50
val fill_in_empty = ("e_fillpatID", TermC.parse_patt @{theory} "?a = _", "e_errpatID")
walther@59971
    51
walther@59911
    52
type record = (fill_in_id * term * thm * Subst.input option);
walther@59822
    53
walther@59909
    54
(*
walther@59909
    55
  check if (agreed result, input formula) matches the error pattern "pat" modulo simplifier rls
walther@59909
    56
*)
walther@59909
    57
fun check_for' (res, inf) subst (id, pat) rls =
Walther@60500
    58
  let
Walther@60500
    59
    val ctxt = Proof_Context.init_global ((ThyC.Isac()))
Walther@60500
    60
    val (res', _, _, rewritten) =
Walther@60509
    61
      Rewrite.rew_sub ctxt 1 subst Rewrite_Ord.function_empty
Walther@60500
    62
        Rule_Set.empty false [] (HOLogic.Trueprop $ pat) res;
neuper@42423
    63
  in
walther@59848
    64
    if rewritten then 
neuper@42423
    65
      let
Walther@60500
    66
        val norm_res = case Rewrite.rewrite_set_inst_ ctxt false subst rls  res' of
walther@59909
    67
            NONE => res'
walther@59909
    68
          | SOME (norm_res, _) => norm_res
Walther@60500
    69
        val norm_inf = case Rewrite.rewrite_set_inst_ ctxt false subst rls inf of
walther@59909
    70
            NONE => inf
walther@59909
    71
          | SOME (norm_inf, _) => norm_inf
walther@59909
    72
      in
walther@59909
    73
        if norm_res = norm_inf then SOME id else NONE
neuper@42423
    74
      end
neuper@42423
    75
    else NONE
neuper@42423
    76
  end;
neuper@42423
    77
walther@59908
    78
(*
walther@59908
    79
  check if (agreed result, input formula) matches SOME error pattern modulo simplifier rls;
walther@59908
    80
  (prog, env) for retrieval of casual substitution for bdv in the pattern.
walther@59908
    81
*)
walther@59844
    82
fun check_for (res, inf) (prog, env) (errpats, rls) =
neuper@42428
    83
  let
walther@59911
    84
    val (_, subst) = Subst.for_bdv prog env
neuper@42428
    85
    fun scan (_, [], _) = NONE
walther@59909
    86
      | scan (id, T :: errpats, _) =
walther@59909
    87
          case check_for' (res, inf) subst (id, T) rls of
walther@59909
    88
            NONE => scan (id, errpats, [])
walther@59909
    89
          | SOME id => SOME id
neuper@42428
    90
    fun scans [] = NONE
neuper@42428
    91
      | scans (group :: groups) =
neuper@42428
    92
          case scan group of
neuper@42428
    93
            NONE => scans groups
walther@59909
    94
          | SOME id => SOME id
neuper@42428
    95
  in scans errpats end;
neuper@42428
    96
neuper@42433
    97
(* fill-in patterns an forms.
neuper@42433
    98
  returns thm required by "fun in_fillform *)
walther@59909
    99
fun fill_form (subs_opt, subst) (thm, form) id (fillpatID, pat, erpaID) =
neuper@42430
   100
  let
Walther@60500
   101
    val ctxt = Proof_Context.init_global ((ThyC.Isac()))
neuper@42430
   102
    val (form', _, _, rewritten) =
Walther@60509
   103
      Rewrite.rew_sub ctxt 1 subst Rewrite_Ord.function_empty Rule_Set.empty false [] (HOLogic.Trueprop $ pat) form;
walther@59909
   104
  in (*the fillpat of the thm must be dedicated to id*)
walther@59909
   105
    if id = erpaID andalso rewritten then
walther@59848
   106
      SOME (fillpatID, HOLogic.mk_eq (form, form'), thm, subs_opt) 
wneuper@59264
   107
    else NONE
wneuper@59264
   108
  end
neuper@42430
   109
walther@59909
   110
fun fill_from_store subst form id thm =
wneuper@59264
   111
  let
wneuper@59264
   112
    val thmDeriv = Thm.get_name_hint thm
walther@59916
   113
    val (part, thyID) = Thy_Read.thy_containing_thm thmDeriv
walther@59876
   114
    val theID = [part, thyID, "Theorems", ThmC.cut_id thmDeriv]
walther@59970
   115
    val fillpats = case Thy_Read.from_store theID of
walther@59917
   116
      Thy_Write.Hthm {fillpats, ...} => fillpats
walther@59909
   117
    | _ => raise ERROR "fill_from_store: uncovered case of get_the"
walther@59909
   118
    val some = map (fill_form subst (thm, form) id) fillpats
wneuper@59264
   119
  in some |> filter is_some |> map the end
neuper@42430
   120
walther@59909
   121
fun find_fill_patterns (pt, pos as (p, _): Pos.pos') id =
neuper@42430
   122
  let 
wneuper@59276
   123
    val f_curr = Ctree.get_curr_formula (pt, pos);
wneuper@59276
   124
    val pp = Ctree.par_pblobj pt p
walther@60154
   125
    val (errpats, prog) = case MethodC.from_store (Ctree.get_obj Ctree.g_metID pt pp) of
wneuper@59416
   126
      {errpats, scr = Rule.Prog prog, ...} => (errpats, prog)
walther@59909
   127
    | _ => raise ERROR "find_fill_patterns: uncovered case of get_met"
walther@59807
   128
    val {env, ...} = Ctree.get_istate_LI pt pos |> Istate.the_pstate
walther@59911
   129
    val subst = Subst.for_bdv prog env
neuper@42430
   130
    val errpatthms = errpats
walther@59909
   131
      |> filter ((curry op = id) o (#1: Error_Pattern_Def.T -> Error_Pattern_Def.id))
walther@59909
   132
      |> map (#3: Error_Pattern_Def.T -> thm list)
neuper@42430
   133
      |> flat
walther@59909
   134
  in map (fill_from_store subst f_curr id) errpatthms |> flat end
neuper@37906
   135
walther@59909
   136
(*
walther@59909
   137
  Check input on a fill-pattern:
walther@59909
   138
  check if input is exactly equal to the rewrite from a rule
walther@59909
   139
  which is stored at the pos where the input is stored of "ok".
walther@59909
   140
*)
walther@59909
   141
fun filled_exactly (pt, pos as (p, _)) istr =
walther@60360
   142
  case TermC.parseNEW (ThyC.get_theory "Isac_Knowledge" |> Proof_Context.init_global) istr of
wneuper@59571
   143
    NONE => ("syntax error in '" ^ istr ^ "'", Tactic.Tac "")
neuper@42437
   144
  | SOME ifo => 
neuper@42437
   145
      let
walther@59757
   146
        val p' = Pos.lev_on p;
wneuper@59276
   147
        val tac = Ctree.get_obj Ctree.g_tac pt p';
neuper@42437
   148
      in 
walther@59921
   149
        case Solve_Step.check tac (pt, pos) of
walther@59920
   150
          Applicable.No msg => (msg, Tactic.Tac "")
walther@59920
   151
        | Applicable.Yes rew =>
neuper@42437
   152
            let
neuper@42437
   153
              val res = case rew of
wneuper@59571
   154
               Tactic.Rewrite_Inst' (_, _, _, _, _, _, _, (res, _)) => res
wneuper@59571
   155
              |Tactic.Rewrite' (_, _, _, _, _, _, (res, _)) => res
walther@59909
   156
              | t => raise ERROR ("filled_exactly: uncovered case for " ^ Tactic.string_of t)
neuper@42437
   157
            in 
walther@59848
   158
              if not (ifo = res) then
walther@59848
   159
                ("input does not exactly fill the gaps", Tactic.Tac "")
neuper@42437
   160
              else ("ok", tac)
neuper@42437
   161
            end
neuper@42437
   162
      end
neuper@42437
   163
neuper@42458
   164
(* fetch errpatIDs from an arbitrary tactic *)
walther@59909
   165
fun from_store tac =
neuper@42458
   166
  let
neuper@42458
   167
    val rlsID =
neuper@42458
   168
      case tac of
wneuper@59571
   169
       Tactic.Rewrite_Set rlsID => rlsID
wneuper@59571
   170
      |Tactic.Rewrite_Set_Inst (_, rlsID) => rlsID
walther@59852
   171
      | _ => "empty"
walther@59916
   172
    val (part, thyID) = Thy_Read.thy_containing_rls "Isac_Knowledge" rlsID;
walther@59970
   173
    val rls = case Thy_Read.from_store [part, thyID, "Rulesets", rlsID] of
walther@59917
   174
      Thy_Write.Hrls {thy_rls = (_, rls), ...} => rls
walther@59909
   175
    | _ => raise ERROR "from_store: uncovered case of get_the"
neuper@42458
   176
  in case rls of
walther@59851
   177
    Rule_Def.Repeat {errpatts, ...} => errpatts
walther@59878
   178
  | Rule_Set.Sequence {errpatts, ...} => errpatts
walther@59850
   179
  | Rule_Set.Rrls {errpatts, ...} => errpatts
walther@59851
   180
  | Rule_Set.Empty => []
neuper@42458
   181
  end
wneuper@59264
   182
walther@59858
   183
(**)end(**)