comparison src/elab_env.sml @ 677:81573f62d6c3

Enforce termination of type class instances
author Adam Chlipala <adamc@hcoop.net>
date Thu, 26 Mar 2009 15:54:04 -0400
parents 43430b7190f4
children f0224c7f12bb
comparison
equal deleted inserted replaced
676:e0c186464612 677:81573f62d6c3
180 join (Int.compare (m1, m2), 180 join (Int.compare (m1, m2),
181 fn () => join (joinL String.compare (ms1, ms2), 181 fn () => join (joinL String.compare (ms1, ms2),
182 fn () => String.compare (x1, x2))) 182 fn () => String.compare (x1, x2)))
183 end 183 end
184 184
185 structure CS = BinarySetFn(CK)
185 structure CM = BinaryMapFn(CK) 186 structure CM = BinaryMapFn(CK)
186 187
187 datatype class_key = 188 datatype class_key =
188 CkNamed of int 189 CkNamed of int
189 | CkRel of int 190 | CkRel of int
695 let 696 let
696 fun clauses (c, hyps) = 697 fun clauses (c, hyps) =
697 case #1 c of 698 case #1 c of
698 TFun (hyp, c) => 699 TFun (hyp, c) =>
699 (case class_pair_in hyp of 700 (case class_pair_in hyp of
700 NONE => NONE 701 SOME (p as (_, CkRel _)) => clauses (c, p :: hyps)
701 | SOME p => clauses (c, p :: hyps)) 702 | _ => NONE)
702 | _ => 703 | _ =>
703 case class_pair_in c of 704 case class_pair_in c of
704 NONE => NONE 705 NONE => NONE
705 | SOME (cn, ck) => 706 | SOME (cn, ck) =>
706 let 707 let
728 (SOME f1, SOME f2) => SOME (f2, Inclusion f1) 729 (SOME f1, SOME f2) => SOME (f2, Inclusion f1)
729 | _ => NONE) 730 | _ => NONE)
730 | _ => quantifiers (c, 0) 731 | _ => quantifiers (c, 0)
731 end 732 end
732 733
734 fun inclusion (classes : class CM.map, init, inclusions, f, e : exp) =
735 let
736 fun search (f, fs) =
737 if f = init then
738 NONE
739 else if CS.member (fs, f) then
740 SOME fs
741 else
742 let
743 val fs = CS.add (fs, f)
744 in
745 case CM.find (classes, f) of
746 NONE => SOME fs
747 | SOME {inclusions = fs', ...} =>
748 CM.foldli (fn (f', _, fs) =>
749 case fs of
750 NONE => NONE
751 | SOME fs => search (f', fs)) (SOME fs) fs'
752 end
753 in
754 case search (f, CS.empty) of
755 SOME _ => CM.insert (inclusions, f, e)
756 | NONE => (ErrorMsg.errorAt (#2 e) "Type class inclusion would create a cycle";
757 inclusions)
758 end
759
733 fun pushENamedAs (env : env) x n t = 760 fun pushENamedAs (env : env) x n t =
734 let 761 let
735 val classes = #classes env 762 val classes = #classes env
736 val classes = case rule_in t of 763 val classes = case rule_in t of
737 NONE => classes 764 NONE => classes
747 Normal (nvars, hyps, x) => 774 Normal (nvars, hyps, x) =>
748 {ground = KM.insert (#ground class, (x, nvars), (hyps, e)), 775 {ground = KM.insert (#ground class, (x, nvars), (hyps, e)),
749 inclusions = #inclusions class} 776 inclusions = #inclusions class}
750 | Inclusion f' => 777 | Inclusion f' =>
751 {ground = #ground class, 778 {ground = #ground class,
752 inclusions = CM.insert (#inclusions class, f', e)} 779 inclusions = inclusion (classes, f, #inclusions class, f', e)}
753 in 780 in
754 CM.insert (classes, f, class) 781 CM.insert (classes, f, class)
755 end 782 end
756 in 783 in
757 {renameK = #renameK env, 784 {renameK = #renameK env,
1111 (globalizeN n, 1138 (globalizeN n,
1112 globalize k)) hyps, e)), 1139 globalize k)) hyps, e)),
1113 inclusions = #inclusions class} 1140 inclusions = #inclusions class}
1114 | Inclusion f' => 1141 | Inclusion f' =>
1115 {ground = #ground class, 1142 {ground = #ground class,
1116 inclusions = CM.insert (#inclusions class, 1143 inclusions = inclusion (classes, cn,
1144 #inclusions class,
1117 globalizeN f', e)} 1145 globalizeN f', e)}
1118 in 1146 in
1119 CM.insert (classes, cn, class) 1147 CM.insert (classes, cn, class)
1120 end 1148 end
1121 in 1149 in
1144 (globalizeN n, 1172 (globalizeN n,
1145 globalize k)) hyps, e)), 1173 globalize k)) hyps, e)),
1146 inclusions = #inclusions class} 1174 inclusions = #inclusions class}
1147 | Inclusion f' => 1175 | Inclusion f' =>
1148 {ground = #ground class, 1176 {ground = #ground class,
1149 inclusions = CM.insert (#inclusions class, 1177 inclusions = inclusion (classes, cn,
1178 #inclusions class,
1150 globalizeN f', e)} 1179 globalizeN f', e)}
1151 in 1180 in
1152 CM.insert (classes, cn, class) 1181 CM.insert (classes, cn, class)
1153 end 1182 end
1154 in 1183 in