Mercurial > urweb
comparison src/elab_env.sml @ 1795:d28adceef22a
Allow type class instances with hypotheses via local ('let') definitions
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Wed, 25 Jul 2012 14:04:59 -0400 |
parents | fca4a6d05ac1 |
children | 0de0daab5fbb |
comparison
equal
deleted
inserted
replaced
1794:4671afac15af | 1795:d28adceef22a |
---|---|
161 | _ => e, | 161 | _ => e, |
162 bind = fn ((xn, rep), U.Exp.RelE _) => (xn+1, liftExpInExp 0 rep) | 162 bind = fn ((xn, rep), U.Exp.RelE _) => (xn+1, liftExpInExp 0 rep) |
163 | ((xn, rep), U.Exp.RelC _) => (xn, liftConInExp 0 rep) | 163 | ((xn, rep), U.Exp.RelC _) => (xn, liftConInExp 0 rep) |
164 | (ctx, _) => ctx} | 164 | (ctx, _) => ctx} |
165 | 165 |
166 val openCon = | |
167 U.Con.existsB {kind = fn ((nk, _), k) => | |
168 case k of | |
169 KRel n => n >= nk | |
170 | _ => false, | |
171 con = fn ((_, nc), c) => | |
172 case c of | |
173 CRel n => n >= nc | |
174 | _ => false, | |
175 bind = fn (all as (nk, nc), b) => | |
176 case b of | |
177 U.Con.RelK _ => (nk+1, nc) | |
178 | U.Con.RelC _ => (nk, nc+1) | |
179 | _ => all} | |
180 (0, 0) | |
181 | |
166 (* Back to environments *) | 182 (* Back to environments *) |
167 | 183 |
168 datatype 'a var' = | 184 datatype 'a var' = |
169 Rel' of int * 'a | 185 Rel' of int * 'a |
170 | Named' of int * 'a | 186 | Named' of int * 'a |
206 end | 222 end |
207 | 223 |
208 structure CS = BinarySetFn(CK) | 224 structure CS = BinarySetFn(CK) |
209 structure CM = BinaryMapFn(CK) | 225 structure CM = BinaryMapFn(CK) |
210 | 226 |
211 type class = {ground : (con * exp) list, | 227 type rules = (int * con list * con * exp) list |
212 rules : (int * con list * con * exp) list} | 228 |
213 val empty_class = {ground = [], | 229 type class = {closedRules : rules, |
214 rules = []} | 230 openRules : rules} |
231 val empty_class = {closedRules = [], | |
232 openRules = []} | |
215 | 233 |
216 type env = { | 234 type env = { |
217 renameK : int SM.map, | 235 renameK : int SM.map, |
218 relK : string list, | 236 relK : string list, |
219 | 237 |
284 namedC = #namedC env, | 302 namedC = #namedC env, |
285 | 303 |
286 datatypes = #datatypes env, | 304 datatypes = #datatypes env, |
287 constructors = #constructors env, | 305 constructors = #constructors env, |
288 | 306 |
289 classes = CM.map (fn cl => {ground = map (fn (c, e) => | 307 classes = CM.map (fn cl => {closedRules = #closedRules cl, |
290 (liftKindInCon 0 c, | 308 openRules = map (fn (nvs, cs, c, e) => |
291 e)) | 309 (nvs, |
292 (#ground cl), | 310 map (liftKindInCon 0) cs, |
293 rules = #rules cl}) | 311 liftKindInCon 0 c, |
312 liftKindInExp 0 e)) | |
313 (#openRules cl)}) | |
294 (#classes env), | 314 (#classes env), |
295 | 315 |
296 renameE = SM.map (fn Rel' (n, c) => Rel' (n, liftKindInCon 0 c) | 316 renameE = SM.map (fn Rel' (n, c) => Rel' (n, liftKindInCon 0 c) |
297 | Named' (n, c) => Named' (n, c)) (#renameE env), | 317 | Named' (n, c) => Named' (n, c)) (#renameE env), |
298 relE = map (fn (x, c) => (x, liftKindInCon 0 c)) (#relE env), | 318 relE = map (fn (x, c) => (x, liftKindInCon 0 c)) (#relE env), |
326 | 346 |
327 datatypes = #datatypes env, | 347 datatypes = #datatypes env, |
328 constructors = #constructors env, | 348 constructors = #constructors env, |
329 | 349 |
330 classes = CM.map (fn class => | 350 classes = CM.map (fn class => |
331 {ground = map (fn (c, e) => | 351 {closedRules = #closedRules class, |
332 (liftConInCon 0 c, | 352 openRules = map (fn (nvs, cs, c, e) => |
333 e)) | 353 (nvs, |
334 (#ground class), | 354 map (liftConInCon 0) cs, |
335 rules = #rules class}) | 355 liftConInCon 0 c, |
356 liftConInExp 0 e)) | |
357 (#openRules class)}) | |
336 (#classes env), | 358 (#classes env), |
337 | 359 |
338 renameE = SM.map (fn Rel' (n, c) => Rel' (n, lift c) | 360 renameE = SM.map (fn Rel' (n, c) => Rel' (n, lift c) |
339 | Named' (n, c) => Named' (n, c)) (#renameE env), | 361 | Named' (n, c) => Named' (n, c)) (#renameE env), |
340 relE = map (fn (x, c) => (x, lift c)) (#relE env), | 362 relE = map (fn (x, c) => (x, lift c)) (#relE env), |
439 | 461 |
440 fun datatypeArgs (xs, _) = xs | 462 fun datatypeArgs (xs, _) = xs |
441 fun constructors (_, dt) = IM.foldri (fn (n, (x, to), ls) => (x, n, to) :: ls) [] dt | 463 fun constructors (_, dt) = IM.foldri (fn (n, (x, to), ls) => (x, n, to) :: ls) [] dt |
442 | 464 |
443 fun listClasses (env : env) = | 465 fun listClasses (env : env) = |
444 map (fn (cn, {ground, rules}) => | 466 map (fn (cn, {closedRules, openRules}) => |
445 (class_name_out cn, | 467 (class_name_out cn, |
446 ground | 468 map (fn (nvs, cs, c, e) => |
447 @ map (fn (nvs, cs, c, e) => | |
448 let | 469 let |
449 val loc = #2 c | 470 val loc = #2 c |
450 val c = foldr (fn (c', c) => (TFun (c', c), loc)) c cs | 471 val c = foldr (fn (c', c) => (TFun (c', c), loc)) c cs |
451 val c = ListUtil.foldli (fn (n, (), c) => (TCFun (Explicit, | 472 val c = ListUtil.foldli (fn (n, (), c) => (TCFun (Explicit, |
452 "x" ^ Int.toString n, | 473 "x" ^ Int.toString n, |
453 (KError, loc), | 474 (KError, loc), |
454 c), loc)) | 475 c), loc)) |
455 c (List.tabulate (nvs, fn _ => ())) | 476 c (List.tabulate (nvs, fn _ => ())) |
456 in | 477 in |
457 (c, e) | 478 (c, e) |
458 end) rules)) (CM.listItemsi (#classes env)) | 479 end) (closedRules @ openRules))) (CM.listItemsi (#classes env)) |
459 | 480 |
460 fun pushClass (env : env) n = | 481 fun pushClass (env : env) n = |
461 {renameK = #renameK env, | 482 {renameK = #renameK env, |
462 relK = #relK env, | 483 relK = #relK env, |
463 | 484 |
651 con = fn d => fn c => | 672 con = fn d => fn c => |
652 case c of | 673 case c of |
653 CRel n => | 674 CRel n => |
654 if n < d then | 675 if n < d then |
655 c | 676 c |
677 else if n - d >= length rs then | |
678 CRel (n - d) | |
656 else | 679 else |
657 #1 (List.nth (rs, n - d)) | 680 #1 (List.nth (rs, n - d)) |
658 | _ => c, | 681 | _ => c, |
659 bind = fn (d, U.Con.RelC _) => d + 1 | 682 bind = fn (d, U.Con.RelC _) => d + 1 |
660 | (d, _) => d} | 683 | (d, _) => d} |
727 | 750 |
728 fun tryRules rules = | 751 fun tryRules rules = |
729 case rules of | 752 case rules of |
730 [] => notFound () | 753 [] => notFound () |
731 | (nRs, cs, c', e) :: rules' => | 754 | (nRs, cs, c', e) :: rules' => |
732 case tryUnify hnorm nRs (c, c') of | 755 case tryUnify hnorm nRs (c, c') of |
733 NONE => tryRules rules' | 756 NONE => tryRules rules' |
734 | SOME rs => | 757 | SOME rs => |
735 let | 758 let |
736 val eos = map (resolve false o unifySubst rs) cs | 759 val eos = map (resolve false o unifySubst rs) cs |
737 in | 760 in |
747 val e = foldl (fn (e', e) => (EApp (e, e'), loc)) e es | 770 val e = foldl (fn (e', e) => (EApp (e, e'), loc)) e es |
748 in | 771 in |
749 SOME e | 772 SOME e |
750 end | 773 end |
751 end | 774 end |
752 | |
753 fun rules () = tryRules (#rules class) | |
754 | |
755 fun tryGrounds ces = | |
756 case ces of | |
757 [] => rules () | |
758 | (c', e) :: ces' => | |
759 case tryUnify hnorm 0 (c, c') of | |
760 NONE => tryGrounds ces' | |
761 | SOME _ => SOME e | |
762 in | 775 in |
763 tryGrounds (#ground class) | 776 tryRules (#openRules class @ #closedRules class) |
764 end | 777 end |
765 in | 778 in |
766 if startsWithUnif c then | 779 if startsWithUnif c then |
767 notFound () | 780 notFound () |
768 else | 781 else |
798 in | 811 in |
799 cause := NONE; | 812 cause := NONE; |
800 resolve true | 813 resolve true |
801 end | 814 end |
802 | 815 |
803 fun pushERel (env : env) x t = | |
804 let | |
805 val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t) | |
806 | x => x) (#renameE env) | |
807 | |
808 val classes = CM.map (fn class => | |
809 {ground = map (fn (c, e) => (c, liftExp e)) (#ground class), | |
810 rules = #rules class}) (#classes env) | |
811 val classes = case class_head_in t of | |
812 NONE => classes | |
813 | SOME f => | |
814 case CM.find (classes, f) of | |
815 NONE => classes | |
816 | SOME class => | |
817 let | |
818 val class = {ground = (t, (ERel 0, #2 t)) :: #ground class, | |
819 rules = #rules class} | |
820 in | |
821 CM.insert (classes, f, class) | |
822 end | |
823 in | |
824 {renameK = #renameK env, | |
825 relK = #relK env, | |
826 | |
827 renameC = #renameC env, | |
828 relC = #relC env, | |
829 namedC = #namedC env, | |
830 | |
831 datatypes = #datatypes env, | |
832 constructors = #constructors env, | |
833 | |
834 classes = classes, | |
835 | |
836 renameE = SM.insert (renameE, x, Rel' (0, t)), | |
837 relE = (x, t) :: #relE env, | |
838 namedE = #namedE env, | |
839 | |
840 renameSgn = #renameSgn env, | |
841 sgn = #sgn env, | |
842 | |
843 renameStr = #renameStr env, | |
844 str = #str env} | |
845 end | |
846 | |
847 fun lookupERel (env : env) n = | |
848 (List.nth (#relE env, n)) | |
849 handle Subscript => raise UnboundRel n | |
850 | |
851 fun rule_in c = | 816 fun rule_in c = |
852 let | 817 let |
853 fun quantifiers (c, nvars) = | 818 fun quantifiers (c, nvars) = |
854 case #1 c of | 819 case #1 c of |
855 TCFun (_, _, _, c) => quantifiers (c, nvars + 1) | 820 CUnif (_, _, _, _, ref (Known c)) => quantifiers (c, nvars) |
821 | TCFun (_, _, _, c) => quantifiers (c, nvars + 1) | |
856 | _ => | 822 | _ => |
857 let | 823 let |
858 fun clauses (c, hyps) = | 824 fun clauses (c, hyps) = |
859 case #1 c of | 825 case #1 c of |
860 TFun (hyp, c) => | 826 TFun (hyp, c) => |
870 end | 836 end |
871 in | 837 in |
872 quantifiers (c, 0) | 838 quantifiers (c, 0) |
873 end | 839 end |
874 | 840 |
841 fun pushERel (env : env) x t = | |
842 let | |
843 val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t) | |
844 | x => x) (#renameE env) | |
845 | |
846 val classes = CM.map (fn class => | |
847 {openRules = map (fn (nvs, cs, c, e) => (nvs, cs, c, liftExp e)) (#openRules class), | |
848 closedRules = #closedRules class}) (#classes env) | |
849 val classes = case rule_in t of | |
850 NONE => classes | |
851 | SOME (f, nvs, cs, c) => | |
852 case CM.find (classes, f) of | |
853 NONE => classes | |
854 | SOME class => | |
855 let | |
856 val rule = (nvs, cs, c, (ERel 0, #2 t)) | |
857 | |
858 val class = | |
859 if openCon t then | |
860 {openRules = rule :: #openRules class, | |
861 closedRules = #closedRules class} | |
862 else | |
863 {closedRules = rule :: #closedRules class, | |
864 openRules = #openRules class} | |
865 in | |
866 CM.insert (classes, f, class) | |
867 end | |
868 in | |
869 {renameK = #renameK env, | |
870 relK = #relK env, | |
871 | |
872 renameC = #renameC env, | |
873 relC = #relC env, | |
874 namedC = #namedC env, | |
875 | |
876 datatypes = #datatypes env, | |
877 constructors = #constructors env, | |
878 | |
879 classes = classes, | |
880 | |
881 renameE = SM.insert (renameE, x, Rel' (0, t)), | |
882 relE = (x, t) :: #relE env, | |
883 namedE = #namedE env, | |
884 | |
885 renameSgn = #renameSgn env, | |
886 sgn = #sgn env, | |
887 | |
888 renameStr = #renameStr env, | |
889 str = #str env} | |
890 end | |
891 | |
892 fun lookupERel (env : env) n = | |
893 (List.nth (#relE env, n)) | |
894 handle Subscript => raise UnboundRel n | |
895 | |
875 fun pushENamedAs (env : env) x n t = | 896 fun pushENamedAs (env : env) x n t = |
876 let | 897 let |
877 val classes = #classes env | 898 val classes = #classes env |
878 val classes = case rule_in t of | 899 val classes = case rule_in t of |
879 NONE => classes | 900 NONE => classes |
883 | SOME class => | 904 | SOME class => |
884 let | 905 let |
885 val e = (ENamed n, #2 t) | 906 val e = (ENamed n, #2 t) |
886 | 907 |
887 val class = | 908 val class = |
888 {ground = #ground class, | 909 {openRules = #openRules class, |
889 rules = (nvs, cs, c, e) :: #rules class} | 910 closedRules = (nvs, cs, c, e) :: #closedRules class} |
890 in | 911 in |
891 CM.insert (classes, f, class) | 912 CM.insert (classes, f, class) |
892 end | 913 end |
893 in | 914 in |
894 {renameK = #renameK env, | 915 {renameK = #renameK env, |
1208 | SOME class => | 1229 | SOME class => |
1209 let | 1230 let |
1210 val e = (EModProj (m1, ms, x), #2 sgn) | 1231 val e = (EModProj (m1, ms, x), #2 sgn) |
1211 | 1232 |
1212 val class = | 1233 val class = |
1213 {ground = #ground class, | 1234 {openRules = #openRules class, |
1214 rules = (nvs, | 1235 closedRules = (nvs, |
1215 map globalize cs, | 1236 map globalize cs, |
1216 globalize c, | 1237 globalize c, |
1217 e) :: #rules class} | 1238 e) :: #closedRules class} |
1218 in | 1239 in |
1219 CM.insert (classes, cn, class) | 1240 CM.insert (classes, cn, class) |
1220 end | 1241 end |
1221 in | 1242 in |
1222 (classes, | 1243 (classes, |
1234 | SOME class => | 1255 | SOME class => |
1235 let | 1256 let |
1236 val e = (EModProj (m1, ms, x), #2 sgn) | 1257 val e = (EModProj (m1, ms, x), #2 sgn) |
1237 | 1258 |
1238 val class = | 1259 val class = |
1239 {ground = #ground class, | 1260 {openRules = #openRules class, |
1240 rules = (nvs, | 1261 closedRules = (nvs, |
1241 map globalize cs, | 1262 map globalize cs, |
1242 globalize c, | 1263 globalize c, |
1243 e) :: #rules class} | 1264 e) :: #closedRules class} |
1244 in | 1265 in |
1245 CM.insert (classes, cn, class) | 1266 CM.insert (classes, cn, class) |
1246 end | 1267 end |
1247 in | 1268 in |
1248 (classes, | 1269 (classes, |