25 val make_axiom_clause : Term.term -> string * int -> clause |
25 val make_axiom_clause : Term.term -> string * int -> clause |
26 val make_conjecture_clause : Term.term -> clause |
26 val make_conjecture_clause : Term.term -> clause |
27 val make_conjecture_clause_thm : Thm.thm -> clause |
27 val make_conjecture_clause_thm : Thm.thm -> clause |
28 val make_hypothesis_clause : Term.term -> clause |
28 val make_hypothesis_clause : Term.term -> clause |
29 val special_equal : bool ref |
29 val special_equal : bool ref |
30 val clause_info : clause -> string * string |
30 val get_axiomName : clause -> string |
31 val typed : unit -> unit |
31 val typed : unit -> unit |
32 val untyped : unit -> unit |
32 val untyped : unit -> unit |
33 val num_of_clauses : clause -> int |
33 val num_of_clauses : clause -> int |
34 |
34 |
35 val dfg_clauses2str : string list -> string |
35 val dfg_clauses2str : string list -> string |
36 val clause2dfg : clause -> string * string list |
36 val clause2dfg : clause -> string * string list |
37 val clauses2dfg : clause list -> string -> clause list -> clause list -> |
37 val clauses2dfg : clause list -> string -> clause list -> clause list -> |
38 (string * int) list -> (string * int) list -> string list -> string |
38 (string * int) list -> (string * int) list -> string list -> string |
39 val tfree_dfg_clause : string -> string |
39 val tfree_dfg_clause : string -> string |
40 |
40 |
41 val tptp_arity_clause : arityClause -> string |
41 val tptp_arity_clause : arityClause -> string |
42 val tptp_classrelClause : classrelClause -> string |
42 val tptp_classrelClause : classrelClause -> string |
43 val tptp_clause : clause -> string list |
43 val tptp_clause : clause -> string list |
68 |
68 |
69 val tvar_prefix = "T_"; |
69 val tvar_prefix = "T_"; |
70 val tfree_prefix = "t_"; |
70 val tfree_prefix = "t_"; |
71 |
71 |
72 val clause_prefix = "cls_"; |
72 val clause_prefix = "cls_"; |
73 |
|
74 val arclause_prefix = "arcls_" |
73 val arclause_prefix = "arcls_" |
|
74 val clrelclause_prefix = "relcls_"; |
75 |
75 |
76 val const_prefix = "c_"; |
76 val const_prefix = "c_"; |
77 val tconst_prefix = "tc_"; |
77 val tconst_prefix = "tc_"; |
78 |
78 |
79 val class_prefix = "class_"; |
79 val class_prefix = "class_"; |
194 |
194 |
195 |
195 |
196 datatype type_literal = LTVar of string | LTFree of string; |
196 datatype type_literal = LTVar of string | LTFree of string; |
197 |
197 |
198 |
198 |
199 datatype folTerm = UVar of string * fol_type| Fun of string * fol_type * folTerm list; |
199 datatype folTerm = UVar of string * fol_type |
|
200 | Fun of string * fol_type * folTerm list; |
200 datatype predicate = Predicate of pred_name * fol_type * folTerm list; |
201 datatype predicate = Predicate of pred_name * fol_type * folTerm list; |
201 |
202 |
202 |
|
203 datatype literal = Literal of polarity * predicate * tag; |
203 datatype literal = Literal of polarity * predicate * tag; |
204 |
|
205 |
204 |
206 datatype typ_var = FOLTVar of indexname | FOLTFree of string; |
205 datatype typ_var = FOLTVar of indexname | FOLTFree of string; |
207 |
206 |
208 |
207 |
209 (* ML datatype used to repsent one single clause: disjunction of literals. *) |
208 (* ML datatype used to repsent one single clause: disjunction of literals. *) |
218 tvars: string list, |
217 tvars: string list, |
219 predicates: (string*int) list, |
218 predicates: (string*int) list, |
220 functions: (string*int) list}; |
219 functions: (string*int) list}; |
221 |
220 |
222 |
221 |
223 |
|
224 exception CLAUSE of string; |
222 exception CLAUSE of string; |
225 |
223 |
226 |
224 |
227 |
|
228 (*** make clauses ***) |
225 (*** make clauses ***) |
|
226 |
|
227 fun isFalse (Literal (pol,Predicate(a,_,[]),_)) = |
|
228 (pol andalso a = "c_False") orelse |
|
229 (not pol andalso a = "c_True") |
|
230 | isFalse _ = false; |
229 |
231 |
230 fun make_clause (clause_id,axiom_name,kind,literals, |
232 fun make_clause (clause_id,axiom_name,kind,literals, |
231 types_sorts,tvar_type_literals, |
233 types_sorts,tvar_type_literals, |
232 tfree_type_literals,tvars, predicates, functions) = |
234 tfree_type_literals,tvars, predicates, functions) = |
233 if null literals |
235 if forall isFalse literals |
234 then error "Problem too trivial for resolution (empty clause)" |
236 then error "Problem too trivial for resolution (empty clause)" |
235 else |
237 else |
236 Clause {clause_id = clause_id, axiom_name = axiom_name, kind = kind, |
238 Clause {clause_id = clause_id, axiom_name = axiom_name, kind = kind, |
237 literals = literals, types_sorts = types_sorts, |
239 literals = literals, types_sorts = types_sorts, |
238 tvar_type_literals = tvar_type_literals, |
240 tvar_type_literals = tvar_type_literals, |
239 tfree_type_literals = tfree_type_literals, |
241 tfree_type_literals = tfree_type_literals, |
240 tvars = tvars, predicates = predicates, |
242 tvars = tvars, predicates = predicates, |
241 functions = functions}; |
243 functions = functions}; |
|
244 |
|
245 |
|
246 (** Some Clause destructor functions **) |
|
247 |
|
248 fun string_of_kind (Clause cls) = name_of_kind (#kind cls); |
|
249 |
|
250 fun get_axiomName (Clause cls) = #axiom_name cls; |
|
251 |
|
252 fun get_clause_id (Clause cls) = #clause_id cls; |
|
253 |
|
254 fun funcs_of_cls (Clause cls) = #functions cls; |
|
255 |
|
256 fun preds_of_cls (Clause cls) = #predicates cls; |
|
257 |
242 |
258 |
243 |
259 |
244 (*Definitions of the current theory--to allow suppressing types.*) |
260 (*Definitions of the current theory--to allow suppressing types.*) |
245 val curr_defs = ref Defs.empty; |
261 val curr_defs = ref Defs.empty; |
246 |
262 |
638 fun classrelClauses_of (sub,sups) = |
654 fun classrelClauses_of (sub,sups) = |
639 case sups of [] => [make_axiom_classrelClause (sub,NONE)] |
655 case sups of [] => [make_axiom_classrelClause (sub,NONE)] |
640 | _ => classrelClauses_of_aux (sub, sups); |
656 | _ => classrelClauses_of_aux (sub, sups); |
641 |
657 |
642 |
658 |
643 |
|
644 (***** convert clauses to DFG format *****) |
|
645 |
|
646 fun string_of_clauseID (Clause cls) = |
|
647 clause_prefix ^ string_of_int (#clause_id cls); |
|
648 |
|
649 fun string_of_kind (Clause cls) = name_of_kind (#kind cls); |
|
650 |
|
651 fun string_of_axiomName (Clause cls) = #axiom_name cls; |
|
652 |
|
653 (****!!!! Changed for typed equality !!!!****) |
659 (****!!!! Changed for typed equality !!!!****) |
654 |
660 |
655 fun wrap_eq_type typ t = eq_typ_wrapper ^"(" ^ t ^ "," ^ typ ^ ")"; |
661 fun wrap_eq_type typ t = eq_typ_wrapper ^"(" ^ t ^ "," ^ typ ^ ")"; |
656 |
662 |
657 (* Only need to wrap equality's arguments with "typeinfo" if the output clauses are typed && if we specifically ask for types to be included. *) |
663 (* Only need to wrap equality's arguments with "typeinfo" if the output clauses are typed && if we specifically ask for types to be included. *) |
684 if !keep_types andalso typ<>"" |
690 if !keep_types andalso typ<>"" |
685 then name ^ (ResLib.list_to_string (terms_as_strings @ [typ])) |
691 then name ^ (ResLib.list_to_string (terms_as_strings @ [typ])) |
686 else name ^ (ResLib.list_to_string terms_as_strings) |
692 else name ^ (ResLib.list_to_string terms_as_strings) |
687 end; |
693 end; |
688 |
694 |
|
695 |
|
696 fun string_of_clausename (cls_id,ax_name) = |
|
697 clause_prefix ^ ascii_of ax_name ^ "_" ^ string_of_int cls_id; |
|
698 |
|
699 fun string_of_type_clsname (cls_id,ax_name,idx) = |
|
700 string_of_clausename (cls_id,ax_name) ^ "_tcs" ^ (string_of_int idx); |
689 |
701 |
690 |
702 |
691 (********************************) |
703 (********************************) |
692 (* Code for producing DFG files *) |
704 (* Code for producing DFG files *) |
693 (********************************) |
705 (********************************) |
712 |
724 |
713 fun forall_close ([],[]) = "" |
725 fun forall_close ([],[]) = "" |
714 | forall_close (vars,tvars) = ")" |
726 | forall_close (vars,tvars) = ")" |
715 |
727 |
716 fun gen_dfg_cls (cls_id,ax_name,knd,lits,tvars,vars) = |
728 fun gen_dfg_cls (cls_id,ax_name,knd,lits,tvars,vars) = |
717 let val ax_str = |
729 "clause( %(" ^ knd ^ ")\n" ^ forall_open(vars,tvars) ^ |
718 if ax_name = "" then cls_id |
730 "or(" ^ lits ^ ")" ^ forall_close(vars,tvars) ^ ",\n" ^ |
719 else cls_id ^ "_" ^ ascii_of ax_name |
731 string_of_clausename (cls_id,ax_name) ^ ")."; |
720 in |
732 |
721 "clause( %(" ^ knd ^ ")\n" ^ forall_open(vars,tvars) ^ |
733 fun gen_dfg_type_cls (cls_id,ax_name,knd,tfree_lit,idx,tvars,vars) = |
722 "or(" ^ lits ^ ")" ^ forall_close(vars,tvars) ^ ",\n" ^ |
734 "clause( %(" ^ knd ^ ")\n" ^ forall_open(vars,tvars) ^ |
723 ax_str ^ ")." |
735 "or( " ^ tfree_lit ^ ")" ^ forall_close(vars,tvars) ^ ",\n" ^ |
724 end; |
736 string_of_type_clsname (cls_id,ax_name,idx) ^ ")."; |
725 |
|
726 fun gen_dfg_type_cls (cls_id,knd,tfree_lit,idx,tvars,vars) = |
|
727 let val ax_str = cls_id ^ "_tcs" ^ (string_of_int idx) |
|
728 in |
|
729 "clause( %(" ^ knd ^ ")\n" ^ forall_open(vars,tvars) ^ |
|
730 "or( " ^ tfree_lit ^ ")" ^ forall_close(vars,tvars) ^ ",\n" ^ |
|
731 ax_str ^ ")." |
|
732 end; |
|
733 |
737 |
734 fun dfg_clause_aux (Clause cls) = |
738 fun dfg_clause_aux (Clause cls) = |
735 let val lits = map dfg_literal (#literals cls) |
739 let val lits = map dfg_literal (#literals cls) |
736 val tvar_lits_strs = |
740 val tvar_lits_strs = |
737 if !keep_types then map dfg_of_typeLit (#tvar_type_literals cls) |
741 if !keep_types then map dfg_of_typeLit (#tvar_type_literals cls) |
785 | string_of_predname (Predicate(name,typ,terms)) = name |
789 | string_of_predname (Predicate(name,typ,terms)) = name |
786 |
790 |
787 |
791 |
788 (* make this return funcs and preds too? *) |
792 (* make this return funcs and preds too? *) |
789 |
793 |
790 fun string_of_predicate (Predicate("equal",typ,terms)) = string_of_equality(typ,terms) |
794 fun string_of_predicate (Predicate("equal",typ,terms)) = |
|
795 string_of_equality(typ,terms) |
791 | string_of_predicate (Predicate(name,_,[])) = name |
796 | string_of_predicate (Predicate(name,_,[])) = name |
792 | string_of_predicate (Predicate(name,typ,terms)) = |
797 | string_of_predicate (Predicate(name,typ,terms)) = |
793 let val terms_as_strings = map string_of_term terms |
798 let val terms_as_strings = map string_of_term terms |
794 in |
799 in |
795 if !keep_types andalso typ<>"" |
800 if !keep_types andalso typ<>"" |
808 fun dfg_clause cls = |
813 fun dfg_clause cls = |
809 let val (lits,tfree_lits) = dfg_clause_aux cls |
814 let val (lits,tfree_lits) = dfg_clause_aux cls |
810 (*"lits" includes the typing assumptions (TVars)*) |
815 (*"lits" includes the typing assumptions (TVars)*) |
811 val vars = dfg_vars cls |
816 val vars = dfg_vars cls |
812 val tvars = dfg_tvars cls |
817 val tvars = dfg_tvars cls |
813 val cls_id = string_of_clauseID cls |
|
814 val ax_name = string_of_axiomName cls |
|
815 val knd = string_of_kind cls |
818 val knd = string_of_kind cls |
816 val lits_str = commas lits |
819 val lits_str = commas lits |
817 val cls_str = gen_dfg_cls(cls_id,ax_name,knd,lits_str,tvars, vars) |
820 val cls_id = get_clause_id cls |
|
821 val axname = get_axiomName cls |
|
822 val cls_str = gen_dfg_cls(cls_id,axname,knd,lits_str,tvars, vars) |
818 fun typ_clss k [] = [] |
823 fun typ_clss k [] = [] |
819 | typ_clss k (tfree :: tfrees) = |
824 | typ_clss k (tfree :: tfrees) = |
820 (gen_dfg_type_cls(cls_id,knd,tfree,k, tvars,vars)) :: |
825 (gen_dfg_type_cls(cls_id,axname,knd,tfree,k, tvars,vars)) :: |
821 (typ_clss (k+1) tfrees) |
826 (typ_clss (k+1) tfrees) |
822 in |
827 in |
823 cls_str :: (typ_clss 0 tfree_lits) |
828 cls_str :: (typ_clss 0 tfree_lits) |
824 end; |
829 end; |
825 |
830 |
826 fun clause_info cls = (string_of_axiomName cls, string_of_clauseID cls); |
831 fun string_of_arity (name, num) = name ^ "," ^ (string_of_int num) |
827 |
|
828 fun funcs_of_cls (Clause cls) = #functions cls; |
|
829 |
|
830 fun preds_of_cls (Clause cls) = #predicates cls; |
|
831 |
|
832 fun string_of_arity (name, num) = name ^"," ^ (string_of_int num) |
|
833 |
832 |
834 fun string_of_preds preds = |
833 fun string_of_preds preds = |
835 "predicates[" ^ (concat_with ", " (map string_of_arity preds)) ^ "].\n"; |
834 "predicates[" ^ (concat_with ", " (map string_of_arity preds)) ^ "].\n"; |
836 |
835 |
837 fun string_of_funcs funcs = |
836 fun string_of_funcs funcs = |
863 |
862 |
864 |
863 |
865 fun clause2dfg cls = |
864 fun clause2dfg cls = |
866 let val (lits,tfree_lits) = dfg_clause_aux cls |
865 let val (lits,tfree_lits) = dfg_clause_aux cls |
867 (*"lits" includes the typing assumptions (TVars)*) |
866 (*"lits" includes the typing assumptions (TVars)*) |
868 val cls_id = string_of_clauseID cls |
867 val cls_id = get_clause_id cls |
869 val ax_name = string_of_axiomName cls |
868 val ax_name = get_axiomName cls |
870 val vars = dfg_vars cls |
869 val vars = dfg_vars cls |
871 val tvars = dfg_tvars cls |
870 val tvars = dfg_tvars cls |
872 val funcs = funcs_of_cls cls |
871 val funcs = funcs_of_cls cls |
873 val preds = preds_of_cls cls |
872 val preds = preds_of_cls cls |
874 val knd = string_of_kind cls |
873 val knd = string_of_kind cls |
909 (*(probname, axioms, conjectures, funcs, preds)*) |
908 (*(probname, axioms, conjectures, funcs, preds)*) |
910 end |
909 end |
911 | clauses2dfg (cls::clss) probname axioms conjectures funcs preds tfrees = |
910 | clauses2dfg (cls::clss) probname axioms conjectures funcs preds tfrees = |
912 let val (lits,tfree_lits) = dfg_clause_aux cls |
911 let val (lits,tfree_lits) = dfg_clause_aux cls |
913 (*"lits" includes the typing assumptions (TVars)*) |
912 (*"lits" includes the typing assumptions (TVars)*) |
914 val cls_id = string_of_clauseID cls |
913 val cls_id = get_clause_id cls |
915 val ax_name = string_of_axiomName cls |
914 val ax_name = get_axiomName cls |
916 val vars = dfg_vars cls |
915 val vars = dfg_vars cls |
917 val tvars = dfg_tvars cls |
916 val tvars = dfg_tvars cls |
918 val funcs' = distinct((funcs_of_cls cls)@funcs) |
917 val funcs' = distinct((funcs_of_cls cls)@funcs) |
919 val preds' = distinct((preds_of_cls cls)@preds) |
918 val preds' = distinct((preds_of_cls cls)@preds) |
920 val knd = string_of_kind cls |
919 val knd = string_of_kind cls |
971 "clause( %(" ^ knd ^ ")\n" ^ "or( " ^ (ResLib.list_to_string' all_lits) ^ ")),\n" ^ |
970 "clause( %(" ^ knd ^ ")\n" ^ "or( " ^ (ResLib.list_to_string' all_lits) ^ ")),\n" ^ |
972 arcls_id ^ ")." |
971 arcls_id ^ ")." |
973 end; |
972 end; |
974 |
973 |
975 |
974 |
976 val clrelclause_prefix = "relcls_"; |
|
977 |
|
978 (* FIX later. Doesn't seem to be used in clasimp *) |
|
979 |
|
980 (*fun tptp_classrelLits sub sup = |
|
981 let val tvar = "(T)" |
|
982 in |
|
983 case sup of NONE => "[++" ^ sub ^ tvar ^ "]" |
|
984 | (SOME supcls) => "[--" ^ sub ^ tvar ^ ",++" ^ supcls ^ tvar ^ "]" |
|
985 end; |
|
986 |
|
987 |
|
988 fun tptp_classrelClause (ClassrelClause cls) = |
|
989 let val relcls_id = clrelclause_prefix ^ string_of_int(#clause_id cls) |
|
990 val sub = #subclass cls |
|
991 val sup = #superclass cls |
|
992 val lits = tptp_classrelLits sub sup |
|
993 in |
|
994 "input_clause(" ^ relcls_id ^ ",axiom," ^ lits ^ ")." |
|
995 end; |
|
996 *) |
|
997 |
|
998 (********************************) |
975 (********************************) |
999 (* code to produce TPTP files *) |
976 (* code to produce TPTP files *) |
1000 (********************************) |
977 (********************************) |
1001 |
978 |
1002 fun tptp_literal (Literal(pol,pred,tag)) = |
979 fun tptp_literal (Literal(pol,pred,tag)) = |
1013 fun tptp_of_typeLit (LTVar x) = "--" ^ x |
990 fun tptp_of_typeLit (LTVar x) = "--" ^ x |
1014 | tptp_of_typeLit (LTFree x) = "++" ^ x; |
991 | tptp_of_typeLit (LTFree x) = "++" ^ x; |
1015 |
992 |
1016 |
993 |
1017 fun gen_tptp_cls (cls_id,ax_name,knd,lits) = |
994 fun gen_tptp_cls (cls_id,ax_name,knd,lits) = |
1018 let val ax_str = (if ax_name = "" then "" else ("_" ^ ascii_of ax_name)) |
995 "input_clause(" ^ string_of_clausename (cls_id,ax_name) ^ "," ^ |
1019 in |
996 knd ^ "," ^ lits ^ ")."; |
1020 "input_clause(" ^ cls_id ^ ax_str ^ "," ^ knd ^ "," ^ lits ^ ")." |
997 |
1021 end; |
998 fun gen_tptp_type_cls (cls_id,ax_name,knd,tfree_lit,idx) = |
1022 |
999 "input_clause(" ^ string_of_type_clsname (cls_id,ax_name,idx) ^ "," ^ |
1023 fun gen_tptp_type_cls (cls_id,knd,tfree_lit,idx) = |
|
1024 "input_clause(" ^ cls_id ^ "_tcs" ^ (string_of_int idx) ^ "," ^ |
|
1025 knd ^ ",[" ^ tfree_lit ^ "])."; |
1000 knd ^ ",[" ^ tfree_lit ^ "])."; |
1026 |
1001 |
1027 fun tptp_clause_aux (Clause cls) = |
1002 fun tptp_clause_aux (Clause cls) = |
1028 let val lits = map tptp_literal (#literals cls) |
1003 let val lits = map tptp_literal (#literals cls) |
1029 val tvar_lits_strs = |
1004 val tvar_lits_strs = |
1039 end; |
1014 end; |
1040 |
1015 |
1041 fun tptp_clause cls = |
1016 fun tptp_clause cls = |
1042 let val (lits,tfree_lits) = tptp_clause_aux cls |
1017 let val (lits,tfree_lits) = tptp_clause_aux cls |
1043 (*"lits" includes the typing assumptions (TVars)*) |
1018 (*"lits" includes the typing assumptions (TVars)*) |
1044 val cls_id = string_of_clauseID cls |
1019 val cls_id = get_clause_id cls |
1045 val ax_name = string_of_axiomName cls |
1020 val ax_name = get_axiomName cls |
1046 val knd = string_of_kind cls |
1021 val knd = string_of_kind cls |
1047 val lits_str = ResLib.list_to_string' lits |
1022 val lits_str = ResLib.list_to_string' lits |
1048 val cls_str = gen_tptp_cls(cls_id,ax_name,knd,lits_str) |
1023 val cls_str = gen_tptp_cls(cls_id,ax_name,knd,lits_str) |
1049 fun typ_clss k [] = [] |
1024 fun typ_clss k [] = [] |
1050 | typ_clss k (tfree :: tfrees) = |
1025 | typ_clss k (tfree :: tfrees) = |
1051 (gen_tptp_type_cls(cls_id,knd,tfree,k)) :: typ_clss (k+1) tfrees |
1026 gen_tptp_type_cls(cls_id,ax_name,knd,tfree,k) :: |
|
1027 typ_clss (k+1) tfrees |
1052 in |
1028 in |
1053 cls_str :: (typ_clss 0 tfree_lits) |
1029 cls_str :: (typ_clss 0 tfree_lits) |
1054 end; |
1030 end; |
1055 |
1031 |
1056 fun clause2tptp cls = |
1032 fun clause2tptp cls = |
1057 let val (lits,tfree_lits) = tptp_clause_aux cls |
1033 let val (lits,tfree_lits) = tptp_clause_aux cls |
1058 (*"lits" includes the typing assumptions (TVars)*) |
1034 (*"lits" includes the typing assumptions (TVars)*) |
1059 val cls_id = string_of_clauseID cls |
1035 val cls_id = get_clause_id cls |
1060 val ax_name = string_of_axiomName cls |
1036 val ax_name = get_axiomName cls |
1061 val knd = string_of_kind cls |
1037 val knd = string_of_kind cls |
1062 val lits_str = ResLib.list_to_string' lits |
1038 val lits_str = ResLib.list_to_string' lits |
1063 val cls_str = gen_tptp_cls(cls_id,ax_name,knd,lits_str) |
1039 val cls_str = gen_tptp_cls(cls_id,ax_name,knd,lits_str) |
1064 in |
1040 in |
1065 (cls_str,tfree_lits) |
1041 (cls_str,tfree_lits) |
1103 val concl_lit = string_of_conclLit arcls |
1079 val concl_lit = string_of_conclLit arcls |
1104 val prems_lits = strings_of_premLits arcls |
1080 val prems_lits = strings_of_premLits arcls |
1105 val knd = string_of_arKind arcls |
1081 val knd = string_of_arKind arcls |
1106 val all_lits = concl_lit :: prems_lits |
1082 val all_lits = concl_lit :: prems_lits |
1107 in |
1083 in |
1108 "input_clause(" ^ arcls_id ^ "," ^ knd ^ "," ^ (ResLib.list_to_string' all_lits) ^ ")." |
1084 "input_clause(" ^ arcls_id ^ "," ^ knd ^ "," ^ |
1109 end; |
1085 (ResLib.list_to_string' all_lits) ^ ")." |
1110 |
1086 end; |
1111 |
|
1112 val clrelclause_prefix = "relcls_"; |
|
1113 |
1087 |
1114 fun tptp_classrelLits sub sup = |
1088 fun tptp_classrelLits sub sup = |
1115 let val tvar = "(T)" |
1089 let val tvar = "(T)" |
1116 in |
1090 in |
1117 case sup of NONE => "[++" ^ sub ^ tvar ^ "]" |
1091 case sup of NONE => "[++" ^ sub ^ tvar ^ "]" |