@@ -154,11 +154,31 @@ let rec update_dominance g q qv =
154154 | Some q' -> update_dominant_if_related g qv q' q in
155155 match QMap. find_opt qv g.delayed_check with
156156 | None -> g'
157- | Some qs ->
158- let g' = QSet. fold (fun v g -> Option. bind g (fun g -> update_dominance g q v)) qs g' in
159- match g' with
160- | Some graph -> Some { graph with delayed_check = QMap. set qv QSet. empty g.delayed_check }
161- | None -> None
157+ | Some delayed_qs ->
158+ (* When two sort variables are `set` to each other, e.g. uState, (q1 <-> q2), without being
159+ dominated, then both delay the domination check of each other:
160+ delayed_check[q1] = {q2}
161+ delayed_check[q2] = {q1}
162+
163+ When one of them becomes dominated, e.g. q1 dominated by Type, then we need to clear up
164+ any occurrence of it in the delayed check of the other, e.g. remove q1 from delayed_check[q2].
165+ Otherwise, we end up in a loop. *)
166+ let remove_qv_from_delayed delayed_q delayed_check =
167+ match QMap. find_opt delayed_q delayed_check with
168+ | None -> delayed_check
169+ | Some dqs ->
170+ QMap. set delayed_q (QSet. remove qv dqs) delayed_check
171+ in
172+ let clearup_cyclic_delay graph =
173+ QSet. fold (fun delayed_q acc_graph ->
174+ { acc_graph with delayed_check = remove_qv_from_delayed delayed_q acc_graph.delayed_check })
175+ delayed_qs graph
176+ in
177+ let g' = Option. map clearup_cyclic_delay g' in
178+ let g' = QSet. fold (fun v g -> Option. bind g (fun g -> update_dominance g q v)) delayed_qs g' in
179+ match g' with
180+ | Some graph -> Some { graph with delayed_check = QMap. set qv QSet. empty g.delayed_check }
181+ | None -> None
162182
163183let update_dominance_if_valid g (q1 ,k ,q2 ) =
164184 match k with
@@ -229,9 +249,8 @@ let enforce_constraint (q1, k, q2) g =
229249 let e = lazy (G. get_explanation (q1,to_graph_cstr k,q2) g.graph) in
230250 raise @@ EliminationError (QualityInconsistency (None , (k, q1, q2, Some (Path e))))
231251 | Some graph ->
232- let g = { g with graph } in
233- if Quality. equal q1 q2 then g
234- else dominance_check g (q1, k, q2)
252+ if Quality. equal q1 q2 then graph
253+ else dominance_check graph (q1, k, q2)
235254
236255let merge_constraints csts g = ElimConstraints. fold enforce_constraint csts g
237256
@@ -296,10 +315,10 @@ let merge g g' =
296315 (fun q acc -> try add_quality q acc with _ -> acc) qs g in
297316 Quality.Set. fold
298317 (fun q -> Quality.Set. fold
299- (fun q' acc -> if Quality. equal q q' then acc
300- else if eliminates_to g' q q'
301- then enforce_eliminates_to q q' acc
302- else acc) qs) qs g
318+ (fun q' acc -> if Quality. equal q q' then acc
319+ else if eliminates_to g' q q'
320+ then enforce_eliminates_to q q' acc
321+ else acc) qs) qs g
303322
304323let is_empty g = QVar.Set. is_empty (qvar_domain g)
305324
0 commit comments