Skip to content

Commit c114619

Browse files
authored
Merge pull request #375 from LPCIC/fix-bug-chr
Fix CHR bug affecting trocq
2 parents b8578d9 + 6ba51a9 commit c114619

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

CHANGES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# v3.4.2 (October 2025)
2+
3+
Requires Menhir 20211230 and OCaml 4.13 or above.
4+
5+
- Runtime:
6+
- Fix bug concerning CHR rules firing on non-fully-dereffed terms
7+
18
# v3.4.1 (September 2025)
29

310
Requires Menhir 20211230 and OCaml 4.13 or above.

elpi.opam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ depends: [
2222
"re" {>= "1.7.2"}
2323
"ppx_deriving" {>= "4.3"}
2424
"ANSITerminal" {with-test}
25-
"cmdliner" {with-test}
25+
"cmdliner" {with-test & < "2.0"}
2626
"fileutils" {with-test}
2727
"yojson" {with-test}
2828
"dune" {>= "2.9.0"}

src/runtime/runtime.ml

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ let xppterm ~nice ?(pp_ctx = { Data.uv_names; table = ! C.table }) ?(min_prec=mi
165165
(* let ppconstant f c = Fmt.fprintf f "%s/%d" (C.show ~table:pp_ctx.table c) c in *)
166166
let ppbuiltin f b = Fmt.fprintf f "%s" @@ show_builtin_predicate ~table:pp_ctx.table C.show b in
167167
let string_of_uvar_body r =
168+
(* Use this to have stable names: "X" ^ string_of_int (uvar_id r) in *)
168169
try IntMap.find (uvar_id r) (fst !(pp_ctx.uv_names))
169170
with Not_found ->
170171
let m, n = !(pp_ctx.uv_names) in
@@ -3464,18 +3465,20 @@ end = struct (* {{{ *)
34643465
let t' = faux (d+1) t in
34653466
if t == t' then orig
34663467
else Lam t'
3468+
(* deref *)
3469+
| UVar(r,ano) when !!r != C.dummy ->
3470+
faux d (deref_uv ~to_:d r ano)
3471+
| AppUVar(r,args) when !!r != C.dummy ->
3472+
faux d (deref_appuv ~to_:d r args)
34673473
(* freeze *)
3468-
| AppUVar(r,args) when r.vardepth == 0 && !!r == C.dummy ->
3474+
| AppUVar(r,args) when r.vardepth == 0 ->
34693475
let args = smart_map (faux d) args in
34703476
App(Global_symbols.uvarc, freeze_uv r, [list_to_lp_list args])
34713477
(* expansion *)
3472-
| UVar(r,ano) when !!r == C.dummy ->
3478+
| UVar(r,ano) ->
34733479
faux d (log_assignment(expand_uv ~depth:d r ~ano))
3474-
| AppUVar(r,args) when !!r == C.dummy ->
3480+
| AppUVar(r,args) ->
34753481
faux d (log_assignment(expand_appuv ~depth:d r ~args))
3476-
(* deref *)
3477-
| UVar(r,ano) -> faux d (deref_uv ~to_:d r ano)
3478-
| AppUVar(r,args) -> faux d (deref_appuv ~to_:d r args)
34793482
in
34803483
[%spy "dev:freeze:in" ~rid (fun fmt () ->
34813484
Fmt.fprintf fmt "depth:%d ground:%d newground:%d maxground:%d %a"
@@ -3794,6 +3797,21 @@ let try_fire_rule (gid[@trace]) rule (constraints as orig_constraints) =
37943797
error "propagation rules must not declare constraint(s)"
37953798
with No_clause -> raise NoMatch in
37963799

3800+
(* Inefficient but sound:
3801+
deref_uv/appuv and freeze cannot be easily interleaved, since
3802+
deref>hmove>move may restrict and generate an assignment.
3803+
eg
3804+
1. X -> frozen-1 (freeze)
3805+
2. X c0 := Y (deref a term containing X c0)
3806+
3. Y -> frozen-2 (freeze)
3807+
4. X derefs to Y -> frozen-2 (freeze)
3808+
3809+
It is unclear when deref restricts, but it happens. Looks like an optimization
3810+
no to restrict ahead-of-time, but I couldn't find where we do it.
3811+
*)
3812+
let constraints_goals = List.map (fun (n,d,t) -> n,d,full_deref ~adepth:0 empty_env ~depth:d t) constraints_goals in
3813+
let constraints_contexts = List.map (fun (n,m,l) -> n,m,l |> List.map (fun { hdepth = depth; hsrc = t } -> { hdepth = depth; hsrc = full_deref ~adepth:0 empty_env ~depth t})) constraints_contexts in
3814+
37973815
let result = try
37983816

37993817
(* matching *)

0 commit comments

Comments
 (0)