src/Pure/Isar/proof_context.ML
changeset 53378 07990ba8c0ea
parent 52223 5bb6ae8acb87
child 53380 08f3491c50bf
equal deleted inserted replaced
53377:21693b7c8fbf 53378:07990ba8c0ea
    29   val default_sort: Proof.context -> indexname -> sort
    29   val default_sort: Proof.context -> indexname -> sort
    30   val consts_of: Proof.context -> Consts.T
    30   val consts_of: Proof.context -> Consts.T
    31   val set_syntax_mode: Syntax.mode -> Proof.context -> Proof.context
    31   val set_syntax_mode: Syntax.mode -> Proof.context -> Proof.context
    32   val restore_syntax_mode: Proof.context -> Proof.context -> Proof.context
    32   val restore_syntax_mode: Proof.context -> Proof.context -> Proof.context
    33   val facts_of: Proof.context -> Facts.T
    33   val facts_of: Proof.context -> Facts.T
    34   val cases_of: Proof.context -> (string * (Rule_Cases.T * bool)) list
       
    35   val map_naming: (Name_Space.naming -> Name_Space.naming) -> Proof.context -> Proof.context
    34   val map_naming: (Name_Space.naming -> Name_Space.naming) -> Proof.context -> Proof.context
    36   val naming_of: Proof.context -> Name_Space.naming
    35   val naming_of: Proof.context -> Name_Space.naming
    37   val restore_naming: Proof.context -> Proof.context -> Proof.context
    36   val restore_naming: Proof.context -> Proof.context -> Proof.context
    38   val full_name: Proof.context -> binding -> string
    37   val full_name: Proof.context -> binding -> string
    39   val class_space: Proof.context -> Name_Space.T
    38   val class_space: Proof.context -> Name_Space.T
   130     (Thm.binding * (string * string list) list) list ->
   129     (Thm.binding * (string * string list) list) list ->
   131     Proof.context -> (string * thm list) list * Proof.context
   130     Proof.context -> (string * thm list) list * Proof.context
   132   val add_assms_i: Assumption.export ->
   131   val add_assms_i: Assumption.export ->
   133     (Thm.binding * (term * term list) list) list ->
   132     (Thm.binding * (term * term list) list) list ->
   134     Proof.context -> (string * thm list) list * Proof.context
   133     Proof.context -> (string * thm list) list * Proof.context
   135   val add_cases: bool -> (string * Rule_Cases.T option) list -> Proof.context -> Proof.context
   134   val dest_cases: Proof.context -> (string * (Rule_Cases.T * bool)) list
       
   135   val update_cases: bool -> (string * Rule_Cases.T option) list -> Proof.context -> Proof.context
   136   val apply_case: Rule_Cases.T -> Proof.context -> (string * term list) list * Proof.context
   136   val apply_case: Rule_Cases.T -> Proof.context -> (string * term list) list * Proof.context
   137   val get_case: Proof.context -> string -> binding option list -> Rule_Cases.T
   137   val check_case: Proof.context -> string * Position.T -> binding option list -> Rule_Cases.T
   138   val type_notation: bool -> Syntax.mode -> (typ * mixfix) list -> Proof.context -> Proof.context
   138   val type_notation: bool -> Syntax.mode -> (typ * mixfix) list -> Proof.context -> Proof.context
   139   val notation: bool -> Syntax.mode -> (term * mixfix) list -> Proof.context -> Proof.context
   139   val notation: bool -> Syntax.mode -> (term * mixfix) list -> Proof.context -> Proof.context
   140   val generic_type_notation: bool -> Syntax.mode -> (typ * mixfix) list -> morphism ->
   140   val generic_type_notation: bool -> Syntax.mode -> (typ * mixfix) list -> morphism ->
   141     Context.generic -> Context.generic
   141     Context.generic -> Context.generic
   142   val generic_notation: bool -> Syntax.mode -> (term * mixfix) list -> morphism ->
   142   val generic_notation: bool -> Syntax.mode -> (term * mixfix) list -> morphism ->
   190 
   190 
   191 
   191 
   192 
   192 
   193 (** Isar proof context information **)
   193 (** Isar proof context information **)
   194 
   194 
       
   195 type cases = ((Rule_Cases.T * bool) * int) Name_Space.table;
       
   196 val empty_cases: cases = Name_Space.empty_table Markup.caseN;
       
   197 
   195 datatype data =
   198 datatype data =
   196   Data of
   199   Data of
   197    {mode: mode,                  (*inner syntax mode*)
   200    {mode: mode,                  (*inner syntax mode*)
   198     syntax: Local_Syntax.T,      (*local syntax*)
   201     syntax: Local_Syntax.T,      (*local syntax*)
   199     tsig: Type.tsig * Type.tsig, (*local/global type signature -- local name space / defsort only*)
   202     tsig: Type.tsig * Type.tsig, (*local/global type signature -- local name space / defsort only*)
   200     consts: Consts.T * Consts.T, (*local/global consts -- local name space / abbrevs only*)
   203     consts: Consts.T * Consts.T, (*local/global consts -- local name space / abbrevs only*)
   201     facts: Facts.T,              (*local facts*)
   204     facts: Facts.T,              (*local facts*)
   202     cases: (string * (Rule_Cases.T * bool)) list};    (*named case contexts*)
   205     cases: cases};               (*named case contexts: case, is_proper, running index*)
   203 
   206 
   204 fun make_data (mode, syntax, tsig, consts, facts, cases) =
   207 fun make_data (mode, syntax, tsig, consts, facts, cases) =
   205   Data {mode = mode, syntax = syntax, tsig = tsig, consts = consts, facts = facts, cases = cases};
   208   Data {mode = mode, syntax = syntax, tsig = tsig, consts = consts, facts = facts, cases = cases};
   206 
   209 
   207 structure Data = Proof_Data
   210 structure Data = Proof_Data
   208 (
   211 (
   209   type T = data;
   212   type T = data;
   210   fun init thy =
   213   fun init thy =
   211     make_data (mode_default, Local_Syntax.init thy,
   214     make_data (mode_default, Local_Syntax.init thy,
   212       (Sign.tsig_of thy, Sign.tsig_of thy),
   215       (Sign.tsig_of thy, Sign.tsig_of thy),
   213       (Sign.consts_of thy, Sign.consts_of thy), Facts.empty, []);
   216       (Sign.consts_of thy, Sign.consts_of thy), Facts.empty, empty_cases);
   214 );
   217 );
   215 
   218 
   216 fun rep_data ctxt = Data.get ctxt |> (fn Data rep => rep);
   219 fun rep_data ctxt = Data.get ctxt |> (fn Data rep => rep);
   217 
   220 
   218 fun map_data f =
   221 fun map_data f =
  1130 
  1133 
  1131 
  1134 
  1132 
  1135 
  1133 (** cases **)
  1136 (** cases **)
  1134 
  1137 
  1135 local
  1138 fun dest_cases ctxt =
  1136 
  1139   Symtab.fold (fn (a, (c, i)) => cons (i, (a, c))) (#2 (cases_of ctxt)) []
  1137 fun rem_case name = remove (fn (x: string, (y, _)) => x = y) name;
  1140   |> sort (int_ord o pairself #1) |> map #2;
  1138 
  1141 
  1139 fun add_case _ ("", _) cases = cases
  1142 local
  1140   | add_case _ (name, NONE) cases = rem_case name cases
  1143 
  1141   | add_case is_proper (name, SOME c) cases = (name, (c, is_proper)) :: rem_case name cases;
  1144 fun update_case _ _ ("", _) res = res
  1142 
  1145   | update_case _ _ (name, NONE) ((space, tab), index) =
  1143 fun prep_case name fxs c =
  1146       let
  1144   let
  1147         val tab' = Symtab.delete_safe name tab;
       
  1148       in ((space, tab'), index) end
       
  1149   | update_case context is_proper (name, SOME c) (cases, index) =
       
  1150       let
       
  1151         val (_, cases') = cases |> Name_Space.define context false
       
  1152           (Binding.make (name, Position.none), ((c, is_proper), index));
       
  1153         val index' = index + 1;
       
  1154       in (cases', index') end;
       
  1155 
       
  1156 fun fix (b, T) ctxt =
       
  1157   let val ([x], ctxt') = add_fixes [(b, SOME T, NoSyn)] ctxt
       
  1158   in (Free (x, T), ctxt') end;
       
  1159 
       
  1160 in
       
  1161 
       
  1162 fun update_cases is_proper args ctxt =
       
  1163   let
       
  1164     val context = Context.Proof ctxt |> Name_Space.map_naming (K Name_Space.default_naming);
       
  1165     val cases = cases_of ctxt;
       
  1166     val index = Symtab.fold (fn _ => Integer.add 1) (#2 cases) 0;
       
  1167     val (cases', _) = fold (update_case context is_proper) args (cases, index);
       
  1168   in map_cases (K cases') ctxt end;
       
  1169 
       
  1170 fun case_result c ctxt =
       
  1171   let
       
  1172     val Rule_Cases.Case {fixes, ...} = c;
       
  1173     val (ts, ctxt') = ctxt |> fold_map fix fixes;
       
  1174     val Rule_Cases.Case {assumes, binds, cases, ...} = Rule_Cases.apply ts c;
       
  1175   in
       
  1176     ctxt'
       
  1177     |> bind_terms (map drop_schematic binds)
       
  1178     |> update_cases true (map (apsnd SOME) cases)
       
  1179     |> pair (assumes, (binds, cases))
       
  1180   end;
       
  1181 
       
  1182 val apply_case = apfst fst oo case_result;
       
  1183 
       
  1184 fun check_case ctxt (name, pos) fxs =
       
  1185   let
       
  1186     val (_, ((Rule_Cases.Case {fixes, assumes, binds, cases}, _), _)) =
       
  1187       Name_Space.check (Context.Proof ctxt) (cases_of ctxt) (name, pos);
       
  1188 
  1145     fun replace (opt_x :: xs) ((y, T) :: ys) = (the_default y opt_x, T) :: replace xs ys
  1189     fun replace (opt_x :: xs) ((y, T) :: ys) = (the_default y opt_x, T) :: replace xs ys
  1146       | replace [] ys = ys
  1190       | replace [] ys = ys
  1147       | replace (_ :: _) [] = error ("Too many parameters for case " ^ quote name);
  1191       | replace (_ :: _) [] =
  1148     val Rule_Cases.Case {fixes, assumes, binds, cases} = c;
  1192           error ("Too many parameters for case " ^ quote name ^ Position.here pos);
  1149     val fixes' = replace fxs fixes;
  1193     val fixes' = replace fxs fixes;
  1150     val binds' = map drop_schematic binds;
  1194     val binds' = map drop_schematic binds;
  1151   in
  1195   in
  1152     if null (fold (Term.add_tvarsT o snd) fixes []) andalso
  1196     if null (fold (Term.add_tvarsT o snd) fixes []) andalso
  1153       null (fold (fold Term.add_vars o snd) assumes []) then
  1197       null (fold (fold Term.add_vars o snd) assumes []) then
  1154         Rule_Cases.Case {fixes = fixes', assumes = assumes, binds = binds', cases = cases}
  1198         Rule_Cases.Case {fixes = fixes', assumes = assumes, binds = binds', cases = cases}
  1155     else error ("Illegal schematic variable(s) in case " ^ quote name)
  1199     else error ("Illegal schematic variable(s) in case " ^ quote name ^ Position.here pos)
  1156   end;
  1200   end;
  1157 
       
  1158 fun fix (b, T) ctxt =
       
  1159   let val ([x], ctxt') = add_fixes [(b, SOME T, NoSyn)] ctxt
       
  1160   in (Free (x, T), ctxt') end;
       
  1161 
       
  1162 in
       
  1163 
       
  1164 fun add_cases is_proper = map_cases o fold (add_case is_proper);
       
  1165 
       
  1166 fun case_result c ctxt =
       
  1167   let
       
  1168     val Rule_Cases.Case {fixes, ...} = c;
       
  1169     val (ts, ctxt') = ctxt |> fold_map fix fixes;
       
  1170     val Rule_Cases.Case {assumes, binds, cases, ...} = Rule_Cases.apply ts c;
       
  1171   in
       
  1172     ctxt'
       
  1173     |> bind_terms (map drop_schematic binds)
       
  1174     |> add_cases true (map (apsnd SOME) cases)
       
  1175     |> pair (assumes, (binds, cases))
       
  1176   end;
       
  1177 
       
  1178 val apply_case = apfst fst oo case_result;
       
  1179 
       
  1180 fun get_case ctxt name xs =
       
  1181   (case AList.lookup (op =) (cases_of ctxt) name of
       
  1182     NONE => error ("Unknown case: " ^ quote name)
       
  1183   | SOME (c, _) => prep_case name xs c);
       
  1184 
  1201 
  1185 end;
  1202 end;
  1186 
  1203 
  1187 
  1204 
  1188 
  1205 
  1276 
  1293 
  1277 in
  1294 in
  1278 
  1295 
  1279 fun pretty_cases ctxt =
  1296 fun pretty_cases ctxt =
  1280   let
  1297   let
  1281     fun add_case (_, (_, false)) = I
  1298     fun mk_case (_, (_, false)) = NONE
  1282       | add_case (name, (c as Rule_Cases.Case {fixes, ...}, true)) =
  1299       | mk_case (name, (c as Rule_Cases.Case {fixes, ...}, true)) =
  1283           cons (name, (fixes, case_result c ctxt));
  1300           SOME (name, (fixes, case_result c ctxt));
  1284     val cases = fold add_case (cases_of ctxt) [];
  1301     val cases = dest_cases ctxt |> map_filter mk_case;
  1285   in
  1302   in
  1286     if null cases then []
  1303     if null cases then []
  1287     else [Pretty.big_list "cases:" (map pretty_case cases)]
  1304     else [Pretty.big_list "cases:" (map pretty_case cases)]
  1288   end;
  1305   end;
  1289 
  1306