80 val empty_funs: code -> string list; |
80 val empty_funs: code -> string list; |
81 val is_cons: code -> string -> bool; |
81 val is_cons: code -> string -> bool; |
82 val contr_classparam_typs: code -> string -> itype option list; |
82 val contr_classparam_typs: code -> string -> itype option list; |
83 |
83 |
84 type transact; |
84 type transact; |
85 val ensure_const: theory -> ((sort -> sort) * Sorts.algebra) * Consts.T |
85 val ensure_const: theory -> (sort -> sort) * Sorts.algebra -> CodeFuncgr.T |
86 -> CodeFuncgr.T -> string -> transact -> string * transact; |
86 -> string -> transact -> string * transact; |
87 val ensure_value: theory -> ((sort -> sort) * Sorts.algebra) * Consts.T |
87 val ensure_value: theory -> (sort -> sort) * Sorts.algebra -> CodeFuncgr.T |
88 -> CodeFuncgr.T -> term |
88 -> term -> transact -> (code * ((typscheme * iterm) * string list)) * transact; |
89 -> transact -> (code * ((typscheme * iterm) * string list)) * transact; |
|
90 val transact: theory -> CodeFuncgr.T |
89 val transact: theory -> CodeFuncgr.T |
91 -> (theory -> ((sort -> sort) * Sorts.algebra) * Consts.T -> CodeFuncgr.T |
90 -> (theory -> (sort -> sort) * Sorts.algebra -> CodeFuncgr.T |
92 -> transact -> 'a * transact) -> code -> 'a * code; |
91 -> transact -> 'a * transact) -> code -> 'a * code; |
93 val add_value_stmt: iterm * itype -> code -> code; |
92 val add_value_stmt: iterm * itype -> code -> code; |
94 end; |
93 end; |
95 |
94 |
96 structure CodeThingol: CODE_THINGOL = |
95 structure CodeThingol: CODE_THINGOL = |
359 |> pair dep |
358 |> pair dep |
360 |> pair name |
359 |> pair name |
361 end; |
360 end; |
362 |
361 |
363 fun transact thy funcgr f code = |
362 fun transact thy funcgr f code = |
364 let |
363 (NONE, code) |
365 val naming = NameSpace.qualified_names NameSpace.default_naming; |
364 |> f thy (Code.operational_algebra thy) funcgr |
366 val consttab = Consts.empty |
365 |-> (fn x => fn (_, code) => (x, code)); |
367 |> fold (fn c => Consts.declare true naming [] (c, CodeFuncgr.typ funcgr c)) |
|
368 (CodeFuncgr.all funcgr); |
|
369 val algbr = (Code.operational_algebra thy, consttab); |
|
370 in |
|
371 (NONE, code) |
|
372 |> f thy algbr funcgr |
|
373 |-> (fn x => fn (_, code) => (x, code)) |
|
374 end; |
|
375 |
366 |
376 |
367 |
377 (* translation kernel *) |
368 (* translation kernel *) |
378 |
369 |
379 fun ensure_class thy (algbr as ((_, algebra), _)) funcgr class = |
370 fun not_wellsorted thy thm ty sort e = |
|
371 let |
|
372 val err_class = Sorts.class_error (Syntax.pp_global thy) e; |
|
373 val err_thm = case thm |
|
374 of SOME thm => "\n(in defining equation " ^ Display.string_of_thm thm ^ ")" | NONE => ""; |
|
375 val err_typ = "Type " ^ Syntax.string_of_typ_global thy ty ^ " not of sort " |
|
376 ^ Syntax.string_of_sort_global thy sort; |
|
377 in error ("Wellsortedness error" ^ err_thm ^ ":\n" ^ err_typ ^ "\n" ^ err_class) end; |
|
378 |
|
379 fun ensure_class thy (algbr as (_, algebra)) funcgr class = |
380 let |
380 let |
381 val superclasses = (Sorts.certify_sort algebra o Sorts.super_classes algebra) class; |
381 val superclasses = (Sorts.certify_sort algebra o Sorts.super_classes algebra) class; |
382 val cs = #params (AxClass.get_info thy class); |
382 val cs = #params (AxClass.get_info thy class); |
383 val class' = CodeName.class thy class; |
383 val class' = CodeName.class thy class; |
384 val stmt_class = |
384 val stmt_class = |
416 end; |
416 end; |
417 val tyco' = CodeName.tyco thy tyco; |
417 val tyco' = CodeName.tyco thy tyco; |
418 in |
418 in |
419 ensure_stmt stmt_datatype tyco' |
419 ensure_stmt stmt_datatype tyco' |
420 end |
420 end |
421 and exprgen_tyvar_sort thy (algbr as ((proj_sort, _), _)) funcgr (v, sort) = |
421 and exprgen_tyvar_sort thy (algbr as (proj_sort, _)) funcgr (v, sort) = |
422 fold_map (ensure_class thy algbr funcgr) (proj_sort sort) |
422 fold_map (ensure_class thy algbr funcgr) (proj_sort sort) |
423 #>> (fn sort => (unprefix "'" v, sort)) |
423 #>> (fn sort => (unprefix "'" v, sort)) |
424 and exprgen_typ thy algbr funcgr (TFree vs) = |
424 and exprgen_typ thy algbr funcgr (TFree vs) = |
425 exprgen_tyvar_sort thy algbr funcgr vs |
425 exprgen_tyvar_sort thy algbr funcgr vs |
426 #>> (fn (v, sort) => ITyVar v) |
426 #>> (fn (v, sort) => ITyVar v) |
427 | exprgen_typ thy algbr funcgr (Type (tyco, tys)) = |
427 | exprgen_typ thy algbr funcgr (Type (tyco, tys)) = |
428 ensure_tyco thy algbr funcgr tyco |
428 ensure_tyco thy algbr funcgr tyco |
429 ##>> fold_map (exprgen_typ thy algbr funcgr) tys |
429 ##>> fold_map (exprgen_typ thy algbr funcgr) tys |
430 #>> (fn (tyco, tys) => tyco `%% tys) |
430 #>> (fn (tyco, tys) => tyco `%% tys) |
431 and exprgen_dicts thy (algbr as ((proj_sort, algebra), consts)) funcgr (ty_ctxt, sort_decl) = |
431 and exprgen_dicts thy (algbr as (proj_sort, algebra)) funcgr thm (ty, sort) = |
432 let |
432 let |
433 val pp = Syntax.pp_global thy; |
433 val pp = Syntax.pp_global thy; |
434 datatype typarg = |
434 datatype typarg = |
435 Global of (class * string) * typarg list list |
435 Global of (class * string) * typarg list list |
436 | Local of (class * class) list * (string * (int * sort)); |
436 | Local of (class * class) list * (string * (int * sort)); |
444 let |
444 let |
445 val sort' = proj_sort sort; |
445 val sort' = proj_sort sort; |
446 in map_index (fn (n, class) => (Local ([], (v, (n, sort'))), class)) sort' end; |
446 in map_index (fn (n, class) => (Local ([], (v, (n, sort'))), class)) sort' end; |
447 val typargs = Sorts.of_sort_derivation pp algebra |
447 val typargs = Sorts.of_sort_derivation pp algebra |
448 {class_relation = class_relation, type_constructor = type_constructor, |
448 {class_relation = class_relation, type_constructor = type_constructor, |
449 type_variable = type_variable} |
449 type_variable = type_variable} (ty, proj_sort sort) |
450 (ty_ctxt, proj_sort sort_decl); |
450 handle Sorts.CLASS_ERROR e => not_wellsorted thy thm ty sort e; |
451 fun mk_dict (Global (inst, yss)) = |
451 fun mk_dict (Global (inst, yss)) = |
452 ensure_inst thy algbr funcgr inst |
452 ensure_inst thy algbr funcgr inst |
453 ##>> (fold_map o fold_map) mk_dict yss |
453 ##>> (fold_map o fold_map) mk_dict yss |
454 #>> (fn (inst, dss) => DictConst (inst, dss)) |
454 #>> (fn (inst, dss) => DictConst (inst, dss)) |
455 | mk_dict (Local (classrels, (v, (k, sort)))) = |
455 | mk_dict (Local (classrels, (v, (k, sort)))) = |
456 fold_map (ensure_classrel thy algbr funcgr) classrels |
456 fold_map (ensure_classrel thy algbr funcgr) classrels |
457 #>> (fn classrels => DictVar (classrels, (unprefix "'" v, (k, length sort)))) |
457 #>> (fn classrels => DictVar (classrels, (unprefix "'" v, (k, length sort)))) |
458 in |
458 in |
459 fold_map mk_dict typargs |
459 fold_map mk_dict typargs |
460 end |
460 end |
461 and exprgen_dict_parms thy (algbr as (_, consts)) funcgr (c, ty_ctxt) = |
|
462 let |
|
463 val ty_decl = Consts.the_type consts c; |
|
464 val (tys, tys_decl) = pairself (curry (Consts.typargs consts) c) (ty_ctxt, ty_decl); |
|
465 val sorts = map (snd o dest_TVar) tys_decl; |
|
466 in |
|
467 fold_map (exprgen_dicts thy algbr funcgr) (tys ~~ sorts) |
|
468 end |
|
469 and exprgen_eq thy algbr funcgr thm = |
461 and exprgen_eq thy algbr funcgr thm = |
470 let |
462 let |
471 val (args, rhs) = (apfst (snd o strip_comb) o Logic.dest_equals |
463 val (args, rhs) = (apfst (snd o strip_comb) o Logic.dest_equals |
472 o Logic.unvarify o prop_of) thm; |
464 o Logic.unvarify o prop_of) thm; |
473 in |
465 in |
474 fold_map (exprgen_term thy algbr funcgr) args |
466 fold_map (exprgen_term thy algbr funcgr (SOME thm)) args |
475 ##>> exprgen_term thy algbr funcgr rhs |
467 ##>> exprgen_term thy algbr funcgr (SOME thm) rhs |
476 #>> rpair thm |
468 #>> rpair thm |
477 end |
469 end |
478 and ensure_inst thy (algbr as ((_, algebra), _)) funcgr (class, tyco) = |
470 and ensure_inst thy (algbr as (_, algebra)) funcgr (class, tyco) = |
479 let |
471 let |
480 val superclasses = (Sorts.certify_sort algebra o Sorts.super_classes algebra) class; |
472 val superclasses = (Sorts.certify_sort algebra o Sorts.super_classes algebra) class; |
481 val classparams = these (try (#params o AxClass.get_info thy) class); |
473 val classparams = these (try (#params o AxClass.get_info thy) class); |
482 val vs = Name.names Name.context "'a" (Sorts.mg_domain algebra tyco [class]); |
474 val vs = Name.names Name.context "'a" (Sorts.mg_domain algebra tyco [class]); |
483 val sorts' = Sorts.mg_domain (Sign.classes_of thy) tyco [class]; |
475 val sorts' = Sorts.mg_domain (Sign.classes_of thy) tyco [class]; |
486 val arity_typ = Type (tyco, map TFree vs); |
478 val arity_typ = Type (tyco, map TFree vs); |
487 val arity_typ' = Type (tyco, map (fn (v, sort) => TVar ((v, 0), sort)) vs'); |
479 val arity_typ' = Type (tyco, map (fn (v, sort) => TVar ((v, 0), sort)) vs'); |
488 fun exprgen_superarity superclass = |
480 fun exprgen_superarity superclass = |
489 ensure_class thy algbr funcgr superclass |
481 ensure_class thy algbr funcgr superclass |
490 ##>> ensure_classrel thy algbr funcgr (class, superclass) |
482 ##>> ensure_classrel thy algbr funcgr (class, superclass) |
491 ##>> exprgen_dicts thy algbr funcgr (arity_typ, [superclass]) |
483 ##>> exprgen_dicts thy algbr funcgr NONE (arity_typ, [superclass]) |
492 #>> (fn ((superclass, classrel), [DictConst (inst, dss)]) => |
484 #>> (fn ((superclass, classrel), [DictConst (inst, dss)]) => |
493 (superclass, (classrel, (inst, dss)))); |
485 (superclass, (classrel, (inst, dss)))); |
494 fun exprgen_classparam_inst (c, ty) = |
486 fun exprgen_classparam_inst (c, ty) = |
495 let |
487 let |
496 val c_inst = Const (c, map_type_tfree (K arity_typ') ty); |
488 val c_inst = Const (c, map_type_tfree (K arity_typ') ty); |
497 val thm = AxClass.unoverload_conv thy (Thm.cterm_of thy c_inst); |
489 val thm = AxClass.unoverload_conv thy (Thm.cterm_of thy c_inst); |
498 val c_ty = (apsnd Logic.unvarifyT o dest_Const o snd |
490 val c_ty = (apsnd Logic.unvarifyT o dest_Const o snd |
499 o Logic.dest_equals o Thm.prop_of) thm; |
491 o Logic.dest_equals o Thm.prop_of) thm; |
500 in |
492 in |
501 ensure_const thy algbr funcgr c |
493 ensure_const thy algbr funcgr c |
502 ##>> exprgen_const thy algbr funcgr c_ty |
494 ##>> exprgen_const thy algbr funcgr (SOME thm) c_ty |
503 #>> (fn (c, IConst c_inst) => ((c, c_inst), thm)) |
495 #>> (fn (c, IConst c_inst) => ((c, c_inst), thm)) |
504 end; |
496 end; |
505 val stmt_inst = |
497 val stmt_inst = |
506 ensure_class thy algbr funcgr class |
498 ensure_class thy algbr funcgr class |
507 ##>> ensure_tyco thy algbr funcgr tyco |
499 ##>> ensure_tyco thy algbr funcgr tyco |
512 Classinst ((class, (tyco, arity)), (superarities, classparams))); |
504 Classinst ((class, (tyco, arity)), (superarities, classparams))); |
513 val inst = CodeName.instance thy (class, tyco); |
505 val inst = CodeName.instance thy (class, tyco); |
514 in |
506 in |
515 ensure_stmt stmt_inst inst |
507 ensure_stmt stmt_inst inst |
516 end |
508 end |
517 and ensure_const thy (algbr as (_, consts)) funcgr c = |
509 and ensure_const thy algbr funcgr c = |
518 let |
510 let |
519 val c' = CodeName.const thy c; |
511 val c' = CodeName.const thy c; |
520 fun stmt_datatypecons tyco = |
512 fun stmt_datatypecons tyco = |
521 ensure_tyco thy algbr funcgr tyco |
513 ensure_tyco thy algbr funcgr tyco |
522 #>> Datatypecons; |
514 #>> Datatypecons; |
544 of SOME class => stmt_classparam class |
536 of SOME class => stmt_classparam class |
545 | NONE => stmt_fun) |
537 | NONE => stmt_fun) |
546 in |
538 in |
547 ensure_stmt stmtgen c' |
539 ensure_stmt stmtgen c' |
548 end |
540 end |
549 and exprgen_term thy algbr funcgr (Const (c, ty)) = |
541 and exprgen_term thy algbr funcgr thm (Const (c, ty)) = |
550 exprgen_app thy algbr funcgr ((c, ty), []) |
542 exprgen_app thy algbr funcgr thm ((c, ty), []) |
551 | exprgen_term thy algbr funcgr (Free (v, _)) = |
543 | exprgen_term thy algbr funcgr thm (Free (v, _)) = |
552 pair (IVar v) |
544 pair (IVar v) |
553 | exprgen_term thy algbr funcgr (Abs (abs as (_, ty, _))) = |
545 | exprgen_term thy algbr funcgr thm (Abs (abs as (_, ty, _))) = |
554 let |
546 let |
555 val (v, t) = Syntax.variant_abs abs; |
547 val (v, t) = Syntax.variant_abs abs; |
556 in |
548 in |
557 exprgen_typ thy algbr funcgr ty |
549 exprgen_typ thy algbr funcgr ty |
558 ##>> exprgen_term thy algbr funcgr t |
550 ##>> exprgen_term thy algbr funcgr thm t |
559 #>> (fn (ty, t) => (v, ty) `|-> t) |
551 #>> (fn (ty, t) => (v, ty) `|-> t) |
560 end |
552 end |
561 | exprgen_term thy algbr funcgr (t as _ $ _) = |
553 | exprgen_term thy algbr funcgr thm (t as _ $ _) = |
562 case strip_comb t |
554 case strip_comb t |
563 of (Const (c, ty), ts) => |
555 of (Const (c, ty), ts) => |
564 exprgen_app thy algbr funcgr ((c, ty), ts) |
556 exprgen_app thy algbr funcgr thm ((c, ty), ts) |
565 | (t', ts) => |
557 | (t', ts) => |
566 exprgen_term thy algbr funcgr t' |
558 exprgen_term thy algbr funcgr thm t' |
567 ##>> fold_map (exprgen_term thy algbr funcgr) ts |
559 ##>> fold_map (exprgen_term thy algbr funcgr thm) ts |
568 #>> (fn (t, ts) => t `$$ ts) |
560 #>> (fn (t, ts) => t `$$ ts) |
569 and exprgen_const thy algbr funcgr (c, ty) = |
561 and exprgen_const thy algbr funcgr thm (c, ty) = |
570 ensure_const thy algbr funcgr c |
562 let |
571 ##>> exprgen_dict_parms thy algbr funcgr (c, ty) |
563 val tys = Sign.const_typargs thy (c, ty); |
572 ##>> fold_map (exprgen_typ thy algbr funcgr) ((fst o Term.strip_type) ty) |
564 val sorts = (map snd o fst o CodeFuncgr.typ funcgr) c; |
573 #>> (fn ((c, iss), tys) => IConst (c, (iss, tys))) |
565 val tys_args = (fst o Term.strip_type) ty; |
574 and exprgen_app_default thy algbr funcgr (c_ty, ts) = |
566 in |
575 exprgen_const thy algbr funcgr c_ty |
567 ensure_const thy algbr funcgr c |
576 ##>> fold_map (exprgen_term thy algbr funcgr) ts |
568 ##>> fold_map (exprgen_dicts thy algbr funcgr thm) (tys ~~ sorts) |
|
569 ##>> fold_map (exprgen_typ thy algbr funcgr) tys_args |
|
570 #>> (fn ((c, iss), tys) => IConst (c, (iss, tys))) |
|
571 end |
|
572 and exprgen_app_default thy algbr funcgr thm (c_ty, ts) = |
|
573 exprgen_const thy algbr funcgr thm c_ty |
|
574 ##>> fold_map (exprgen_term thy algbr funcgr thm) ts |
577 #>> (fn (t, ts) => t `$$ ts) |
575 #>> (fn (t, ts) => t `$$ ts) |
578 and exprgen_case thy algbr funcgr n cases (app as ((c, ty), ts)) = |
576 and exprgen_case thy algbr funcgr thm n cases (app as ((c, ty), ts)) = |
579 let |
577 let |
580 val (tys, _) = |
578 val (tys, _) = |
581 (chop (1 + (if null cases then 1 else length cases)) o fst o strip_type) ty; |
579 (chop (1 + (if null cases then 1 else length cases)) o fst o strip_type) ty; |
582 val dt = nth ts n; |
580 val dt = nth ts n; |
583 val dty = nth tys n; |
581 val dty = nth tys n; |
593 val ([v_ty], body) = Term.strip_abs_eta 1 (the_single (nth_drop n ts)) |
591 val ([v_ty], body) = Term.strip_abs_eta 1 (the_single (nth_drop n ts)) |
594 in [(Free v_ty, body)] end |
592 in [(Free v_ty, body)] end |
595 | mk_ds cases = map_filter (uncurry mk_case) |
593 | mk_ds cases = map_filter (uncurry mk_case) |
596 (AList.make (CodeUnit.no_args thy) cases ~~ nth_drop n ts); |
594 (AList.make (CodeUnit.no_args thy) cases ~~ nth_drop n ts); |
597 in |
595 in |
598 exprgen_term thy algbr funcgr dt |
596 exprgen_term thy algbr funcgr thm dt |
599 ##>> exprgen_typ thy algbr funcgr dty |
597 ##>> exprgen_typ thy algbr funcgr dty |
600 ##>> fold_map (fn (pat, body) => exprgen_term thy algbr funcgr pat |
598 ##>> fold_map (fn (pat, body) => exprgen_term thy algbr funcgr thm pat |
601 ##>> exprgen_term thy algbr funcgr body) (mk_ds cases) |
599 ##>> exprgen_term thy algbr funcgr thm body) (mk_ds cases) |
602 ##>> exprgen_app_default thy algbr funcgr app |
600 ##>> exprgen_app_default thy algbr funcgr thm app |
603 #>> (fn (((dt, dty), ds), t0) => ICase (((dt, dty), ds), t0)) |
601 #>> (fn (((dt, dty), ds), t0) => ICase (((dt, dty), ds), t0)) |
604 end |
602 end |
605 and exprgen_app thy algbr funcgr ((c, ty), ts) = case Code.get_case_data thy c |
603 and exprgen_app thy algbr funcgr thm ((c, ty), ts) = case Code.get_case_data thy c |
606 of SOME (n, cases) => let val i = 1 + (if null cases then 1 else length cases) in |
604 of SOME (n, cases) => let val i = 1 + (if null cases then 1 else length cases) in |
607 if length ts < i then |
605 if length ts < i then |
608 let |
606 let |
609 val k = length ts; |
607 val k = length ts; |
610 val tys = (curry Library.take (i - k) o curry Library.drop k o fst o strip_type) ty; |
608 val tys = (curry Library.take (i - k) o curry Library.drop k o fst o strip_type) ty; |
611 val ctxt = (fold o fold_aterms) |
609 val ctxt = (fold o fold_aterms) |
612 (fn Free (v, _) => Name.declare v | _ => I) ts Name.context; |
610 (fn Free (v, _) => Name.declare v | _ => I) ts Name.context; |
613 val vs = Name.names ctxt "a" tys; |
611 val vs = Name.names ctxt "a" tys; |
614 in |
612 in |
615 fold_map (exprgen_typ thy algbr funcgr) tys |
613 fold_map (exprgen_typ thy algbr funcgr) tys |
616 ##>> exprgen_case thy algbr funcgr n cases ((c, ty), ts @ map Free vs) |
614 ##>> exprgen_case thy algbr funcgr thm n cases ((c, ty), ts @ map Free vs) |
617 #>> (fn (tys, t) => map2 (fn (v, _) => pair v) vs tys `|--> t) |
615 #>> (fn (tys, t) => map2 (fn (v, _) => pair v) vs tys `|--> t) |
618 end |
616 end |
619 else if length ts > i then |
617 else if length ts > i then |
620 exprgen_case thy algbr funcgr n cases ((c, ty), Library.take (i, ts)) |
618 exprgen_case thy algbr funcgr thm n cases ((c, ty), Library.take (i, ts)) |
621 ##>> fold_map (exprgen_term thy algbr funcgr) (Library.drop (i, ts)) |
619 ##>> fold_map (exprgen_term thy algbr funcgr thm) (Library.drop (i, ts)) |
622 #>> (fn (t, ts) => t `$$ ts) |
620 #>> (fn (t, ts) => t `$$ ts) |
623 else |
621 else |
624 exprgen_case thy algbr funcgr n cases ((c, ty), ts) |
622 exprgen_case thy algbr funcgr thm n cases ((c, ty), ts) |
625 end |
623 end |
626 | NONE => exprgen_app_default thy algbr funcgr ((c, ty), ts); |
624 | NONE => exprgen_app_default thy algbr funcgr thm ((c, ty), ts); |
627 |
625 |
628 |
626 |
629 (** evaluation **) |
627 (** evaluation **) |
630 |
628 |
631 fun add_value_stmt (t, ty) code = |
629 fun add_value_stmt (t, ty) code = |
639 val vs = fold_term_types (K (fold_atyps (insert (eq_fst op =) |
637 val vs = fold_term_types (K (fold_atyps (insert (eq_fst op =) |
640 o dest_TFree))) t []; |
638 o dest_TFree))) t []; |
641 val stmt_value = |
639 val stmt_value = |
642 fold_map (exprgen_tyvar_sort thy algbr funcgr) vs |
640 fold_map (exprgen_tyvar_sort thy algbr funcgr) vs |
643 ##>> exprgen_typ thy algbr funcgr ty |
641 ##>> exprgen_typ thy algbr funcgr ty |
644 ##>> exprgen_term thy algbr funcgr t |
642 ##>> exprgen_term thy algbr funcgr NONE t |
645 #>> (fn ((vs, ty), t) => Fun ((vs, ty), [(([], t), Drule.dummy_thm)])); |
643 #>> (fn ((vs, ty), t) => Fun ((vs, ty), [(([], t), Drule.dummy_thm)])); |
646 fun term_value (dep, code1) = |
644 fun term_value (dep, code1) = |
647 let |
645 let |
648 val Fun ((vs, ty), [(([], t), _)]) = |
646 val Fun ((vs, ty), [(([], t), _)]) = |
649 Graph.get_node code1 CodeName.value_name; |
647 Graph.get_node code1 CodeName.value_name; |