src/Pure/Isar/expression.ML
changeset 28859 d50b523c55db
parent 28852 5ddea758679b
child 28862 53f13f763d4f
equal deleted inserted replaced
28858:855e61829e22 28859:d50b523c55db
   106         [Pretty.str "The above error(s) occurred in expression:", Pretty.brk 1,
   106         [Pretty.str "The above error(s) occurred in expression:", Pretty.brk 1,
   107           pretty_expr thy (Expr expr)])
   107           pretty_expr thy (Expr expr)])
   108   in error err_msg end;
   108   in error err_msg end;
   109 
   109 
   110 
   110 
   111 (** Internalise locale names **)
   111 (** Internalise locale names in expr **)
   112 
   112 
   113 fun intern_expr thy (Expr instances) = Expr (map (apfst (NewLocale.intern thy)) instances);
   113 fun intern thy (Expr instances) = Expr (map (apfst (NewLocale.intern thy)) instances);
   114 
   114 
   115 
   115 
   116 (** Parameters of expression (not expression_i).
   116 (** Parameters of expression.
   117    Sanity check of instantiations.
   117    Sanity check of instantiations.
   118    Positional instantiations are extended to match full length of parameter list. **)
   118    Positional instantiations are extended to match full length of parameter list. **)
   119 
   119 
   120 fun parameters thy (expr, fixed : (Name.binding * string option * mixfix) list) =
   120 fun parameters_of thy (expr, fixed) =
   121   let
   121   let
   122     fun reject_dups message xs =
   122     fun reject_dups message xs =
   123       let val dups = duplicates (op =) xs
   123       let val dups = duplicates (op =) xs
   124       in
   124       in
   125         if null dups then () else error (message ^ commas dups)
   125         if null dups then () else error (message ^ commas dups)
   128     fun match_bind (n, b) = (n = Name.name_of b);
   128     fun match_bind (n, b) = (n = Name.name_of b);
   129     fun bind_eq (b1, b2) = (Name.name_of b1 = Name.name_of b2);
   129     fun bind_eq (b1, b2) = (Name.name_of b1 = Name.name_of b2);
   130       (* FIXME: cannot compare bindings for equality. *)
   130       (* FIXME: cannot compare bindings for equality. *)
   131 
   131 
   132     fun params_loc loc =
   132     fun params_loc loc =
   133           (NewLocale.params_of thy loc |> map (fn (p, _, mx) => (p, mx)), loc)
   133           (NewLocale.params_of thy loc |> map (fn (p, _, mx) => (p, mx)), loc);
   134             handle ERROR msg => err_in_expr thy msg (Expr [(loc, ("", Named []))]);
       
   135     fun params_inst (expr as (loc, (prfx, Positional insts))) =
   134     fun params_inst (expr as (loc, (prfx, Positional insts))) =
   136           let
   135           let
   137             val (ps, loc') = params_loc loc;
   136             val (ps, loc') = params_loc loc;
   138 	    val d = length ps - length insts;
   137 	    val d = length ps - length insts;
   139 	    val insts' =
   138 	    val insts' =
   146             (ps', (loc', (prfx, Positional insts')))
   145             (ps', (loc', (prfx, Positional insts')))
   147           end
   146           end
   148       | params_inst (expr as (loc, (prfx, Named insts))) =
   147       | params_inst (expr as (loc, (prfx, Named insts))) =
   149           let
   148           let
   150             val _ = reject_dups "Duplicate instantiation of the following parameter(s): "
   149             val _ = reject_dups "Duplicate instantiation of the following parameter(s): "
   151               (map fst insts)
   150               (map fst insts);
   152               handle ERROR msg => err_in_expr thy msg (Expr [expr]);
       
   153 
   151 
   154             val (ps, loc') = params_loc loc;
   152             val (ps, loc') = params_loc loc;
   155             val ps' = fold (fn (p, _) => fn ps =>
   153             val ps' = fold (fn (p, _) => fn ps =>
   156               if AList.defined match_bind ps p then AList.delete match_bind p ps
   154               if AList.defined match_bind ps p then AList.delete match_bind p ps
   157               else err_in_expr thy (quote p ^" not a parameter of instantiated expression.")
   155               else error (quote p ^" not a parameter of instantiated expression.")) insts ps;
   158                 (Expr [expr])) insts ps;
       
   159           in
   156           in
   160             (ps', (loc', (prfx, Named insts)))
   157             (ps', (loc', (prfx, Named insts)))
   161           end;
   158           end;
   162     fun params_expr (Expr is) =
   159     fun params_expr (Expr is) =
   163           let
   160           let
   166                 val (ps', i') = params_inst i;
   163                 val (ps', i') = params_inst i;
   167                 val ps'' = AList.join bind_eq (fn p => fn (mx1, mx2) =>
   164                 val ps'' = AList.join bind_eq (fn p => fn (mx1, mx2) =>
   168                   (* FIXME: should check for bindings being the same.
   165                   (* FIXME: should check for bindings being the same.
   169                      Instead we check for equal name and syntax. *)
   166                      Instead we check for equal name and syntax. *)
   170                   if mx1 = mx2 then mx1
   167                   if mx1 = mx2 then mx1
   171                   else err_in_expr thy ("Conflicting syntax for parameter" ^ quote (Name.name_of p) ^ " in expression.")
   168                   else error ("Conflicting syntax for parameter" ^ quote (Name.name_of p) ^
   172                     (Expr is)) (ps, ps')
   169                     " in expression.")) (ps, ps')
   173               in (i', ps'') end) is []
   170               in (i', ps'') end) is []
   174           in
   171           in
   175             (ps', Expr is')
   172             (ps', Expr is')
   176           end;
   173           end;
   177 
   174 
   178     val (parms, expr') = params_expr expr;
   175     val (parms, expr') = params_expr expr;
   179 
   176 
   180     val parms' = map (fst #> Name.name_of) parms;
   177     val parms' = map (#1 #> Name.name_of) parms;
   181     val fixed' = map (#1 #> Name.name_of) fixed;
   178     val fixed' = map (#1 #> Name.name_of) fixed;
   182     val _ = reject_dups "Duplicate fixed parameter(s): " fixed';
   179     val _ = reject_dups "Duplicate fixed parameter(s): " fixed';
   183     val _ = reject_dups "Parameter(s) declared simultaneously in expression and for clause: " (parms' @ fixed');
   180     val _ = reject_dups "Parameter(s) declared simultaneously in expression and for clause: " (parms' @ fixed');
   184 
   181 
   185   in (expr', (parms, fixed)) end;
   182   in (expr', (map (fn (b, mx) => (b, NONE, mx)) parms @ fixed)) end;
   186 
   183 
   187 
   184 
   188 (** Read instantiation **)
   185 (** Read instantiation **)
   189 
   186 
   190 fun read_inst parse_term parms (prfx, insts) ctxt =
   187 local
       
   188 
       
   189 fun prep_inst parse_term parms (prfx, insts) ctxt =
   191   let
   190   let
   192     (* parameters *)
   191     (* parameters *)
   193     val (parm_names, parm_types) = split_list parms;
   192     val (parm_names, parm_types) = split_list parms;
   194     val type_parm_names = fold Term.add_tfreesT parm_types [] |> map fst;
   193     val type_parm_names = fold Term.add_tfreesT parm_types [] |> map fst;
   195 
   194 
   219     val inst = Symtab.make insts'';
   218     val inst = Symtab.make insts'';
   220   in
   219   in
   221     (Element.inst_morphism (ProofContext.theory_of ctxt) (instT, inst) $>
   220     (Element.inst_morphism (ProofContext.theory_of ctxt) (instT, inst) $>
   222       Morphism.name_morphism (Name.qualified prfx), ctxt')
   221       Morphism.name_morphism (Name.qualified prfx), ctxt')
   223   end;
   222   end;
       
   223 
       
   224 in
       
   225 
       
   226 fun read_inst x = prep_inst Syntax.parse_term x;
       
   227 (* fun cert_inst x = prep_inst (K I) x; *)
       
   228 
       
   229 end;
       
   230 
   224         
   231         
   225         
   232 (** Test code **)
   226 (** Debugging **)
       
   227   
   233   
   228 fun debug_parameters raw_expr ctxt =
   234 fun debug_parameters raw_expr ctxt =
   229   let
   235   let
   230     val thy = ProofContext.theory_of ctxt;
   236     val thy = ProofContext.theory_of ctxt;
   231     val expr = apfst (intern_expr thy) raw_expr;
   237     val expr = apfst (intern thy) raw_expr;
   232     val (expr', (parms, fixed)) = parameters thy expr;
   238     val (expr', fixed) = parameters_of thy expr;
   233   in ctxt end;
   239   in ctxt end;
   234 
   240 
   235 
   241 
   236 fun debug_context (raw_expr, fixed) ctxt =
   242 fun debug_context (raw_expr, fixed) ctxt =
   237   let
   243   let
   238     val thy = ProofContext.theory_of ctxt;
   244     val thy = ProofContext.theory_of ctxt;
   239     val expr = intern_expr thy raw_expr;
   245     val expr = intern thy raw_expr;
   240     val (expr', (parms, fixed)) = parameters thy (expr, fixed);
   246     val (expr', fixed) = parameters_of thy (expr, fixed);
   241 
   247 
   242     fun declare_parameters (parms, fixed) ctxt =
   248     fun declare_parameters fixed ctxt =
   243       let
   249       let
   244       val (parms', ctxt') =
   250       val (fixed', ctxt') = ProofContext.add_fixes fixed ctxt;
   245         ProofContext.add_fixes (map (fn (p, mx) => (p, NONE, mx)) parms) ctxt;
       
   246       val (fixed', ctxt'') =
       
   247         ProofContext.add_fixes fixed ctxt';
       
   248       in
   251       in
   249         (parms' @ fixed', ctxt'')
   252         (fixed', ctxt')
   250       end;
   253       end;
   251 
   254 
   252     fun rough_inst loc prfx insts ctxt =
   255     fun rough_inst loc prfx insts ctxt =
   253       let
   256       let
   254         (* locale data *)
   257         (* locale data *)
   302         ctxt''
   305         ctxt''
   303       end;
   306       end;
   304 
   307 
   305     val Expr [(loc1, (prfx1, insts1))] = expr';
   308     val Expr [(loc1, (prfx1, insts1))] = expr';
   306     val ctxt0 = ProofContext.init thy;
   309     val ctxt0 = ProofContext.init thy;
   307     val (parms, ctxt') = declare_parameters (parms, fixed) ctxt0;
   310     val (parms, ctxt') = declare_parameters fixed ctxt0;
   308     val (morph1, ctxt'') = rough_inst loc1 prfx1 insts1 ctxt';
   311     val (morph1, ctxt'') = rough_inst loc1 prfx1 insts1 ctxt';
   309     val ctxt'' = add_declarations loc1 morph1 ctxt';
   312     val ctxt'' = add_declarations loc1 morph1 ctxt';
   310   in ctxt0 end;
   313   in ctxt0 end;
   311 
   314 
   312 
   315 
   346 fun check_autofix_elems elems concl ctxt =
   349 fun check_autofix_elems elems concl ctxt =
   347   let
   350   let
   348     val termss = elems |> map extract_elem;
   351     val termss = elems |> map extract_elem;
   349     val all_terms' = (burrow o burrow_fst) (Syntax.check_terms ctxt) (concl @ flat termss); 
   352     val all_terms' = (burrow o burrow_fst) (Syntax.check_terms ctxt) (concl @ flat termss); 
   350 (*    val (ctxt', all_props') = ProofContext.check_propp_schematic (ctxt, concl @ flat propss); *)
   353 (*    val (ctxt', all_props') = ProofContext.check_propp_schematic (ctxt, concl @ flat propss); *)
   351 val _ = "check" |> warning;
       
   352 val _ = PolyML.makestring all_terms' |> warning;
       
   353     val (concl', terms') = chop (length concl) all_terms';
   354     val (concl', terms') = chop (length concl) all_terms';
   354     val ctxt'' = (fold o fold) (fn (t, _) => Variable.auto_fixes t) terms' ctxt;
   355     val ctxt'' = (fold o fold) (fn (t, _) => Variable.auto_fixes t) terms' ctxt;
   355   in (terms' |> unflat termss |> curry (op ~~) elems |> map restore_elem, concl', ctxt'') end;
   356   in (terms' |> unflat termss |> curry (op ~~) elems |> map restore_elem, concl', ctxt'') end;
   356 
   357 
   357 
   358 
   474       prep_concl raw_concl;
   475       prep_concl raw_concl;
   475 
   476 
   476     (* Retrieve parameter types *) 
   477     (* Retrieve parameter types *) 
   477     val xs = fold (fn Fixes fixes => (fn ps => ps @ map (Name.name_of o #1) fixes) |
   478     val xs = fold (fn Fixes fixes => (fn ps => ps @ map (Name.name_of o #1) fixes) |
   478       _ => fn ps => ps) elems [];
   479       _ => fn ps => ps) elems [];
   479     val (Ts, _) = fold_map ProofContext.inferred_param xs ctxt; 
   480     val (Ts, ctxt') = fold_map ProofContext.inferred_param xs ctxt; 
   480     val parms = xs ~~ Ts;
   481     val parms = xs ~~ Ts;
   481 
   482 
   482     val (elems', text) = finish_elems ctxt parms do_close elems ((([], []), ([], [])), ([], [], []));
   483     val (elems', text) = finish_elems ctxt' parms do_close elems ((([], []), ([], [])), ([], [], []));
   483     (* text has the following structure:
   484     (* text has the following structure:
   484            (((exts, exts'), (ints, ints')), (xs, env, defs))
   485            (((exts, exts'), (ints, ints')), (xs, env, defs))
   485        where
   486        where
   486          exts: external assumptions (terms in external assumes elements)
   487          exts: external assumptions (terms in external assumes elements)
   487          exts': dito, normalised wrt. env
   488          exts': dito, normalised wrt. env
   518 fun prep_context_statement prep_expr prep_elems
   519 fun prep_context_statement prep_expr prep_elems
   519     do_close imprt elements raw_concl context =
   520     do_close imprt elements raw_concl context =
   520   let
   521   let
   521     val thy = ProofContext.theory_of context;
   522     val thy = ProofContext.theory_of context;
   522 
   523 
   523     val (expr, (params, fors)) = parameters thy (apfst (prep_expr thy) imprt);
   524     val (expr, fixed) = parameters_of thy (apfst (prep_expr thy) imprt);
   524     val ctxt = context |>
   525     val ctxt = context |> ProofContext.add_fixes fixed |> snd;
   525       ProofContext.add_fixes (map (fn (b, mx) => (b, NONE, mx)) params) |> snd |>
       
   526       ProofContext.add_fixes fors |> snd;
       
   527   in
   526   in
   528     case expr of
   527     case expr of
   529         Expr [] => let
   528         Expr [] => let
   530           val ((parms, elems, concl), (spec, (_, _, defs))) = prep_elems do_close
   529           val ((parms, elems, concl), (spec, (_, _, defs))) = prep_elems do_close
   531             context elements raw_concl;
   530             context elements raw_concl;
   545 end
   544 end
   546 
   545 
   547 in
   546 in
   548 
   547 
   549 fun read_context imprt body ctxt =
   548 fun read_context imprt body ctxt =
   550   #1 (prep_context_statement intern_expr read_elems true imprt body [] ctxt);
   549   #1 (prep_context_statement intern read_elems true imprt body [] ctxt);
   551 fun cert_context imprt body ctxt =
   550 fun cert_context imprt body ctxt =
   552   #1 (prep_context_statement (K I) cert_elems true imprt body [] ctxt);
   551   #1 (prep_context_statement (K I) cert_elems true imprt body [] ctxt);
   553 
   552 
   554 end;
   553 end;
   555 
   554