src/Tools/isac/Interpret/error-pattern.sml
author Walther Neuper <walther.neuper@jku.at>
Wed, 08 Apr 2020 14:24:38 +0200
changeset 59854 c20d08e01ad2
parent 59852 ea7e6679080e
child 59857 cbb3fae0381d
permissions -rw-r--r--
separate struct ThyC

note: here is much outdated stuff due to many changes in Isabelle;
there is much to unify, probably all can be dropped now in 2020.
     1 (* Handle user-input during the specify- and the solve-phase. 
     2    author: Walther Neuper
     3    0603
     4    (c) due to copyright terms
     5 *)
     6 
     7 signature ERROR_PATTERN =
     8 sig
     9   val find_fillpatterns : Calc.T -> Rule.errpatID -> (Celem.fillpatID * term * thm * Selem.subs option) list
    10   val is_exactly_equal : Calc.T -> string -> string * Tactic.input
    11   val concat_deriv : 'a * ((term * term) list -> term * term -> bool) ->
    12     Rule_Set.T -> Rule.rule list -> term -> term -> bool * (term * Rule.rule * (term * term list)) list
    13   val mk_tacis: Rule_Def.rew_ord' * 'a -> Rule_Set.T -> term * Rule.rule * (term * term list) -> Tactic.input * Tactic.T * (Pos.pos' * (Istate.T * Proof.context))
    14   val fetchErrorpatterns : Tactic.input -> Rule.errpatID list
    15   val check_for :
    16     term * term ->
    17     term * (term * term) list -> (Rule.errpatID * term list * 'a list) list * Rule_Set.T -> Rule.errpatID option
    18   val rule2thm'' : Rule.rule -> Celem.thm''
    19   val rule2rls' : Rule.rule -> string
    20 (* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
    21   (*  NONE *)
    22 (*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
    23   val dropwhile' : ('a -> 'b -> bool) -> 'a list -> 'b list -> 'a list * 'b list
    24   val rev_deriv' : 'a * Rule.rule * ('b * 'c) -> 'b * Rule.rule * ('a * 'c)
    25   val check_err_patt : term * term -> Rule.subst -> Rule.errpatID * term -> Rule_Set.T -> Rule.errpatID option
    26   val get_fillform :
    27      'a * (term * term) list -> 'b * term -> Rule.errpatID -> Celem.fillpat -> (Celem.fillpatID * term * 'b * 'a) option
    28   val get_fillpats :
    29      'a * (term * term) list -> term -> Rule.errpatID -> thm -> (Celem.fillpatID * term * thm * 'a) list
    30 ( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
    31 
    32 end
    33 (**)
    34 structure Error_Pattern(**): ERROR_PATTERN(**) =
    35 struct
    36 (**)
    37 
    38 fun rule2thm'' (Rule.Thm (id, thm)) = (id, thm)
    39   | rule2thm'' r = error ("rule2thm': not defined for " ^ Rule_Set.rule2str r);
    40 fun rule2rls' (Rule.Rls_ rls) = Rule_Set.id_rls rls
    41   | rule2rls' r = error ("rule2rls': not defined for " ^ Rule_Set.rule2str r);
    42 
    43 (*the lists contain eq-al elem-pairs at the beginning;
    44   return first list reverted (again) - ie. in order as required subsequently*)
    45 fun dropwhile' equal (f1::f2::fs) (i1::i2::is) =
    46     if equal f1 i1 then
    47       if equal f2 i2 then dropwhile' equal (f2 :: fs) (i2 :: is)
    48       else (rev (f1 :: f2 :: fs), i1 :: i2 :: is)
    49     else error "dropwhile': did not start with equal elements"
    50   | dropwhile' equal (f::fs) [i] =
    51     if equal f i then
    52       (rev (f::fs), [i])
    53     else error "dropwhile': did not start with equal elements"
    54   | dropwhile' equal [f] (i::is) =
    55     if equal f i then
    56       ([f], i::is)
    57     else error "dropwhile': did not start with equal elements"
    58   | dropwhile' _ _ _ = error "dropwhile': uncovered case"
    59 
    60 (* 040214: version for concat_deriv *)
    61 fun rev_deriv' (t, r, (t', a)) = (t', Rtools.sym_rule r, (t, a));
    62 
    63 fun mk_tacis ro erls (t, r as Rule.Thm (id, thm), (t', a)) = 
    64       (Tactic.Rewrite (id, thm), 
    65         Tactic.Rewrite' ("Isac_Knowledge", fst ro, erls, false, rule2thm'' r, t, (t', a)),
    66        (Pos.e_pos'(*to be updated before generate tacis!!!*), (Istate.Uistate, ContextC.empty)))
    67   | mk_tacis _ _ (t, r as Rule.Rls_ rls, (t', a)) = 
    68       (Tactic.Rewrite_Set (rule2rls' r), 
    69         Tactic.Rewrite_Set' ("Isac_Knowledge", false, rls, t, (t', a)),
    70        (Pos.e_pos'(*to be updated before generate tacis!!!*), (Istate.Uistate, ContextC.empty)))
    71   | mk_tacis _ _ (t, r, _) = error ("mk_tacis: not impl. for " ^ Rule_Set.rule2str r ^ " at " ^ Rule.term2str t)
    72 
    73 (* fo = ifo excluded already in inform *)
    74 fun concat_deriv rew_ord erls rules fo ifo =
    75   let 
    76     fun derivat ([]:(term * Rule.rule * (term * term list)) list) = Rule.e_term
    77       | derivat dt = (#1 o #3 o last_elem) dt
    78     fun equal (_,_,(t1, _)) (_,_,(t2, _)) = t1=t2
    79     val  fod = Rtools.make_deriv (ThyC.Isac()) erls rules (snd rew_ord) NONE  fo
    80     val ifod = Rtools.make_deriv (ThyC.Isac()) erls rules (snd rew_ord) NONE ifo
    81   in 
    82     case (fod, ifod) of
    83       ([], []) => if fo = ifo then (true, []) else (false, [])
    84     | (fod, []) => if derivat fod = ifo then (true, fod) (*ifo is normal form*) else (false, [])
    85     | ([], ifod) => if fo = derivat ifod then (true, ((map rev_deriv') o rev) ifod) else (false, [])
    86     | (fod, ifod) =>
    87       if derivat fod = derivat ifod (*common normal form found*) then
    88         let 
    89           val (fod', rifod') = dropwhile' equal (rev fod) (rev ifod)
    90         in (true, fod' @ (map rev_deriv' rifod')) end
    91       else (false, [])
    92   end
    93 
    94 (*** handle an error pattern ***)
    95 
    96 (* check if (agreed result, input formula) matches the error pattern "pat" modulo simplifier rls *)
    97 fun check_err_patt (res, inf) subst (errpatID, pat) rls =
    98   let 
    99     val (res', _, _, rewritten) =
   100       Rewrite.rew_sub (ThyC.Isac()) 1 subst Rule.e_rew_ord Rule_Set.empty false [] (HOLogic.Trueprop $ pat) res;
   101   in
   102     if rewritten then 
   103       let
   104         val norm_res = case Rewrite.rewrite_set_inst_ (ThyC.Isac()) false subst rls  res' of
   105           NONE => res'
   106         | SOME (norm_res, _) => norm_res
   107         val norm_inf = case Rewrite.rewrite_set_inst_ (ThyC.Isac()) false subst rls inf of
   108           NONE => inf
   109         | SOME (norm_inf, _) => norm_inf
   110       in if norm_res = norm_inf then SOME errpatID else NONE
   111       end
   112     else NONE
   113   end;
   114 
   115 (* check if (agreed result, input formula) matches SOME error pattern modulo simplifier rls;
   116    (prog, env) for retrieval of casual substitution for bdv in the pattern. *)
   117 fun check_for (res, inf) (prog, env) (errpats, rls) =
   118   let
   119     val (_, subst) = Rtools.get_bdv_subst prog env
   120     fun scan (_, [], _) = NONE
   121       | scan (errpatID, errpat :: errpats, _) =
   122           case check_err_patt (res, inf) subst (errpatID, errpat) rls of
   123             NONE => scan (errpatID, errpats, [])
   124           | SOME errpatID => SOME errpatID
   125     fun scans [] = NONE
   126       | scans (group :: groups) =
   127           case scan group of
   128             NONE => scans groups
   129           | SOME errpatID => SOME errpatID
   130   in scans errpats end;
   131 
   132 (* fill-in patterns an forms.
   133   returns thm required by "fun in_fillform *)
   134 fun get_fillform (subs_opt, subst) (thm, form) errpatID (fillpatID, pat, erpaID) =
   135   let
   136     val (form', _, _, rewritten) =
   137       Rewrite.rew_sub (ThyC.Isac()) 1 subst Rule.e_rew_ord Rule_Set.empty false [] (HOLogic.Trueprop $ pat) form;
   138   in (*the fillpat of the thm must be dedicated to errpatID*)
   139     if errpatID = erpaID andalso rewritten then
   140       SOME (fillpatID, HOLogic.mk_eq (form, form'), thm, subs_opt) 
   141     else NONE
   142   end
   143 
   144 fun get_fillpats subst form errpatID thm =
   145   let
   146     val thmDeriv = Thm.get_name_hint thm
   147     val (part, thyID) = Rtools.thy_containing_thm thmDeriv
   148     val theID = [part, thyID, "Theorems", Celem.thmID_of_derivation_name thmDeriv]
   149     val fillpats = case Specify.get_the theID of
   150       Celem.Hthm {fillpats, ...} => fillpats
   151     | _ => error "get_fillpats: uncovered case of get_the"
   152     val some = map (get_fillform subst (thm, form) errpatID) fillpats
   153   in some |> filter is_some |> map the end
   154 
   155 fun find_fillpatterns (pt, pos as (p, _): Pos.pos') errpatID =
   156   let 
   157     val f_curr = Ctree.get_curr_formula (pt, pos);
   158     val pp = Ctree.par_pblobj pt p
   159     val (errpats, prog) = case Specify.get_met (Ctree.get_obj Ctree.g_metID pt pp) of
   160       {errpats, scr = Rule.Prog prog, ...} => (errpats, prog)
   161     | _ => error "find_fillpatterns: uncovered case of get_met"
   162     val {env, ...} = Ctree.get_istate_LI pt pos |> Istate.the_pstate
   163     val subst = Rtools.get_bdv_subst prog env
   164     val errpatthms = errpats
   165       |> filter ((curry op = errpatID) o (#1: Rule.errpat -> Rule.errpatID))
   166       |> map (#3: Rule.errpat -> thm list)
   167       |> flat
   168   in map (get_fillpats subst f_curr errpatID) errpatthms |> flat end
   169 
   170 (* check if an input formula is exactly equal the rewrite from a rule
   171    which is stored at the pos where the input is stored of "ok". *)
   172 fun is_exactly_equal (pt, pos as (p, _)) istr =
   173   case TermC.parseNEW (Celem.assoc_thy "Isac_Knowledge" |> ThyC.thy2ctxt) istr of
   174     NONE => ("syntax error in '" ^ istr ^ "'", Tactic.Tac "")
   175   | SOME ifo => 
   176       let
   177         val p' = Pos.lev_on p;
   178         val tac = Ctree.get_obj Ctree.g_tac pt p';
   179       in 
   180         case Applicable.applicable_in pos pt tac of
   181           Applicable.Notappl msg => (msg, Tactic.Tac "")
   182         | Applicable.Appl rew =>
   183             let
   184               val res = case rew of
   185                Tactic.Rewrite_Inst' (_, _, _, _, _, _, _, (res, _)) => res
   186               |Tactic.Rewrite' (_, _, _, _, _, _, (res, _)) => res
   187               | t => error ("is_exactly_equal: uncovered case for " ^ Tactic.string_of t)
   188             in 
   189               if not (ifo = res) then
   190                 ("input does not exactly fill the gaps", Tactic.Tac "")
   191               else ("ok", tac)
   192             end
   193       end
   194 
   195 (* fetch errpatIDs from an arbitrary tactic *)
   196 fun fetchErrorpatterns tac =
   197   let
   198     val rlsID =
   199       case tac of
   200        Tactic.Rewrite_Set rlsID => rlsID
   201       |Tactic.Rewrite_Set_Inst (_, rlsID) => rlsID
   202       | _ => "empty"
   203     val (part, thyID) = Rtools.thy_containing_rls "Isac_Knowledge" rlsID;
   204     val rls = case Specify.get_the [part, thyID, "Rulesets", rlsID] of
   205       Celem.Hrls {thy_rls = (_, rls), ...} => rls
   206     | _ => error "fetchErrorpatterns: uncovered case of get_the"
   207   in case rls of
   208     Rule_Def.Repeat {errpatts, ...} => errpatts
   209   | Rule_Set.Seqence {errpatts, ...} => errpatts
   210   | Rule_Set.Rrls {errpatts, ...} => errpatts
   211   | Rule_Set.Empty => []
   212   end
   213 
   214 (**)
   215 end
   216 (**)