src/Tools/isac/Interpret/error-fill-pattern.sml
author Walther Neuper <walther.neuper@jku.at>
Thu, 23 Apr 2020 15:48:31 +0200
changeset 59908 9af7dd257f47
parent 59907 4c62e16e842e
permissions -rw-r--r--
separate struct.State_Steps, rename
neuper@37906
     1
(* Handle user-input during the specify- and the solve-phase. 
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@59858
    10
signature ERROR_FILL_PATTERN =
wneuper@59262
    11
sig
walther@59858
    12
  type errpatID = Rule_Def.errpatID
walther@59858
    13
  type errpat = errpatID * term list * thm list
walther@59858
    14
  val errpats2str : errpat list -> string
walther@59858
    15
walther@59906
    16
  val find_fillpatterns : Calc.T -> Error_Fill_Def.errpatID ->
walther@59906
    17
    (Error_Fill_Def.fillpatID * term * thm * Selem.subs option) list
walther@59906
    18
  val fetchErrorpatterns : Tactic.input -> Error_Fill_Def.errpatID list
walther@59775
    19
  val is_exactly_equal : Calc.T -> string -> string * Tactic.input
walther@59906
    20
  val check_for : term * term -> term * (term * term) list ->
walther@59906
    21
    (Error_Fill_Def.errpatID * term list * 'a list) list * Rule_Set.T ->
walther@59906
    22
      Error_Fill_Def.errpatID option
walther@59906
    23
wneuper@59310
    24
(* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
wneuper@59310
    25
  (*  NONE *)
walther@59886
    26
(*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
walther@59863
    27
  val check_err_patt : term * term -> UnparseC.subst -> Error_Fill_Def.errpatID * term -> Rule_Set.T -> Error_Fill_Def.errpatID option
wneuper@59262
    28
  val get_fillform :
walther@59858
    29
     'a * (term * term) list -> 'b * term -> Error_Fill_Def.errpatID -> Error_Fill_Def.fillpat -> (Error_Fill_Def.fillpatID * term * 'b * 'a) option
wneuper@59262
    30
  val get_fillpats :
walther@59858
    31
     'a * (term * term) list -> term -> Error_Fill_Def.errpatID -> thm -> (Error_Fill_Def.fillpatID * term * thm * 'a) list
walther@59886
    32
( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
wneuper@59310
    33
wneuper@59262
    34
end
walther@59822
    35
(**)
walther@59858
    36
structure Error_Fill_Pattern(**): ERROR_FILL_PATTERN(**) =
walther@59822
    37
struct
walther@59822
    38
(**)
neuper@37906
    39
walther@59858
    40
type errpatID = Rule_Def.errpatID
walther@59858
    41
walther@59822
    42
neuper@42428
    43
(* check if (agreed result, input formula) matches the error pattern "pat" modulo simplifier rls *)
wneuper@59405
    44
fun check_err_patt (res, inf) subst (errpatID, pat) rls =
neuper@42423
    45
  let 
neuper@42423
    46
    val (res', _, _, rewritten) =
walther@59857
    47
      Rewrite.rew_sub (ThyC.Isac()) 1 subst Rewrite_Ord.e_rew_ord Rule_Set.empty false [] (HOLogic.Trueprop $ pat) res;
neuper@42423
    48
  in
walther@59848
    49
    if rewritten then 
neuper@42423
    50
      let
walther@59854
    51
        val norm_res = case Rewrite.rewrite_set_inst_ (ThyC.Isac()) false subst rls  res' of
neuper@42423
    52
          NONE => res'
neuper@42423
    53
        | SOME (norm_res, _) => norm_res
walther@59854
    54
        val norm_inf = case Rewrite.rewrite_set_inst_ (ThyC.Isac()) false subst rls inf of
neuper@42423
    55
          NONE => inf
neuper@42423
    56
        | SOME (norm_inf, _) => norm_inf
neuper@42423
    57
      in if norm_res = norm_inf then SOME errpatID else NONE
neuper@42423
    58
      end
neuper@42423
    59
    else NONE
neuper@42423
    60
  end;
neuper@42423
    61
walther@59908
    62
(*
walther@59908
    63
  check if (agreed result, input formula) matches SOME error pattern modulo simplifier rls;
walther@59908
    64
  (prog, env) for retrieval of casual substitution for bdv in the pattern.
walther@59908
    65
*)
walther@59844
    66
fun check_for (res, inf) (prog, env) (errpats, rls) =
neuper@42428
    67
  let
wneuper@59263
    68
    val (_, subst) = Rtools.get_bdv_subst prog env
neuper@42428
    69
    fun scan (_, [], _) = NONE
neuper@42428
    70
      | scan (errpatID, errpat :: errpats, _) =
wneuper@59405
    71
          case check_err_patt (res, inf) subst (errpatID, errpat) rls of
neuper@42428
    72
            NONE => scan (errpatID, errpats, [])
neuper@42428
    73
          | SOME errpatID => SOME errpatID
neuper@42428
    74
    fun scans [] = NONE
neuper@42428
    75
      | scans (group :: groups) =
neuper@42428
    76
          case scan group of
neuper@42428
    77
            NONE => scans groups
neuper@42428
    78
          | SOME errpatID => SOME errpatID
neuper@42428
    79
  in scans errpats end;
neuper@42428
    80
neuper@42433
    81
(* fill-in patterns an forms.
neuper@42433
    82
  returns thm required by "fun in_fillform *)
wneuper@59405
    83
fun get_fillform (subs_opt, subst) (thm, form) errpatID (fillpatID, pat, erpaID) =
neuper@42430
    84
  let
neuper@42430
    85
    val (form', _, _, rewritten) =
walther@59857
    86
      Rewrite.rew_sub (ThyC.Isac()) 1 subst Rewrite_Ord.e_rew_ord Rule_Set.empty false [] (HOLogic.Trueprop $ pat) form;
neuper@42430
    87
  in (*the fillpat of the thm must be dedicated to errpatID*)
walther@59848
    88
    if errpatID = erpaID andalso rewritten then
walther@59848
    89
      SOME (fillpatID, HOLogic.mk_eq (form, form'), thm, subs_opt) 
wneuper@59264
    90
    else NONE
wneuper@59264
    91
  end
neuper@42430
    92
neuper@42430
    93
fun get_fillpats subst form errpatID thm =
wneuper@59264
    94
  let
wneuper@59264
    95
    val thmDeriv = Thm.get_name_hint thm
wneuper@59264
    96
    val (part, thyID) = Rtools.thy_containing_thm thmDeriv
walther@59876
    97
    val theID = [part, thyID, "Theorems", ThmC.cut_id thmDeriv]
wneuper@59269
    98
    val fillpats = case Specify.get_the theID of
walther@59898
    99
      Thy_Html.Hthm {fillpats, ...} => fillpats
wneuper@59264
   100
    | _ => error "get_fillpats: uncovered case of get_the"
wneuper@59264
   101
    val some = map (get_fillform subst (thm, form) errpatID) fillpats
wneuper@59264
   102
  in some |> filter is_some |> map the end
neuper@42430
   103
walther@59846
   104
fun find_fillpatterns (pt, pos as (p, _): Pos.pos') errpatID =
neuper@42430
   105
  let 
wneuper@59276
   106
    val f_curr = Ctree.get_curr_formula (pt, pos);
wneuper@59276
   107
    val pp = Ctree.par_pblobj pt p
wneuper@59276
   108
    val (errpats, prog) = case Specify.get_met (Ctree.get_obj Ctree.g_metID pt pp) of
wneuper@59416
   109
      {errpats, scr = Rule.Prog prog, ...} => (errpats, prog)
wneuper@59264
   110
    | _ => error "find_fillpatterns: uncovered case of get_met"
walther@59807
   111
    val {env, ...} = Ctree.get_istate_LI pt pos |> Istate.the_pstate
wneuper@59263
   112
    val subst = Rtools.get_bdv_subst prog env
neuper@42430
   113
    val errpatthms = errpats
walther@59858
   114
      |> filter ((curry op = errpatID) o (#1: Error_Fill_Def.errpat -> Error_Fill_Def.errpatID))
walther@59858
   115
      |> map (#3: Error_Fill_Def.errpat -> thm list)
neuper@42430
   116
      |> flat
wneuper@59264
   117
  in map (get_fillpats subst f_curr errpatID) errpatthms |> flat end
neuper@37906
   118
walther@59906
   119
(* check if an input formula is exactly equal to the rewrite from a rule
neuper@42437
   120
   which is stored at the pos where the input is stored of "ok". *)
neuper@42437
   121
fun is_exactly_equal (pt, pos as (p, _)) istr =
walther@59881
   122
  case TermC.parseNEW (ThyC.get_theory "Isac_Knowledge" |> ThyC.to_ctxt) istr of
wneuper@59571
   123
    NONE => ("syntax error in '" ^ istr ^ "'", Tactic.Tac "")
neuper@42437
   124
  | SOME ifo => 
neuper@42437
   125
      let
walther@59757
   126
        val p' = Pos.lev_on p;
wneuper@59276
   127
        val tac = Ctree.get_obj Ctree.g_tac pt p';
neuper@42437
   128
      in 
wneuper@59272
   129
        case Applicable.applicable_in pos pt tac of
walther@59735
   130
          Applicable.Notappl msg => (msg, Tactic.Tac "")
walther@59735
   131
        | Applicable.Appl rew =>
neuper@42437
   132
            let
neuper@42437
   133
              val res = case rew of
wneuper@59571
   134
               Tactic.Rewrite_Inst' (_, _, _, _, _, _, _, (res, _)) => res
wneuper@59571
   135
              |Tactic.Rewrite' (_, _, _, _, _, _, (res, _)) => res
walther@59728
   136
              | t => error ("is_exactly_equal: uncovered case for " ^ Tactic.string_of t)
neuper@42437
   137
            in 
walther@59848
   138
              if not (ifo = res) then
walther@59848
   139
                ("input does not exactly fill the gaps", Tactic.Tac "")
neuper@42437
   140
              else ("ok", tac)
neuper@42437
   141
            end
neuper@42437
   142
      end
neuper@42437
   143
neuper@42458
   144
(* fetch errpatIDs from an arbitrary tactic *)
neuper@42458
   145
fun fetchErrorpatterns tac =
neuper@42458
   146
  let
neuper@42458
   147
    val rlsID =
neuper@42458
   148
      case tac of
wneuper@59571
   149
       Tactic.Rewrite_Set rlsID => rlsID
wneuper@59571
   150
      |Tactic.Rewrite_Set_Inst (_, rlsID) => rlsID
walther@59852
   151
      | _ => "empty"
wneuper@59592
   152
    val (part, thyID) = Rtools.thy_containing_rls "Isac_Knowledge" rlsID;
wneuper@59269
   153
    val rls = case Specify.get_the [part, thyID, "Rulesets", rlsID] of
walther@59898
   154
      Thy_Html.Hrls {thy_rls = (_, rls), ...} => rls
wneuper@59264
   155
    | _ => error "fetchErrorpatterns: uncovered case of get_the"
neuper@42458
   156
  in case rls of
walther@59851
   157
    Rule_Def.Repeat {errpatts, ...} => errpatts
walther@59878
   158
  | Rule_Set.Sequence {errpatts, ...} => errpatts
walther@59850
   159
  | Rule_Set.Rrls {errpatts, ...} => errpatts
walther@59851
   160
  | Rule_Set.Empty => []
neuper@42458
   161
  end
wneuper@59264
   162
walther@59858
   163
type errpatID = Rule_Def.errpatID
walther@59858
   164
type errpat =
walther@59858
   165
  errpatID    (* one identifier for a list of patterns                       
walther@59858
   166
                 DESIGN ?TODO: errpatID list for hierarchy of errpats ?      *)
walther@59858
   167
  * term list (* error patterns                                              *)
walther@59858
   168
  * thm list  (* thms related to error patterns; note that respective lhs 
walther@59858
   169
                 do not match (which reflects student's error).
walther@59858
   170
                 fillpatterns are stored with these thms.                    *)
walther@59858
   171
fun errpat2str (id, tms, thms) =
walther@59875
   172
  "(\"" ^ id ^ "\",\n" ^ UnparseC.terms tms ^ ",\n" ^ ThmC.string_of_thms thms
walther@59858
   173
fun errpats2str errpats = (strs2str' o (map errpat2str)) errpats
walther@59858
   174
walther@59858
   175
(**)end(**)