Hello. I just noticed an interesting behaviour with declare_constraint
. It seems like the context at the moment of suspending the goal is not available in the CHR, but comes back when the goal is resumed. Here is a minimal example:
pred p o:int.
p X :- var X, !, declare_constraint (p X) [X].
p X :- if ctx (coq.say X) (coq.say "no").
constraint p {
rule (p X) <=> (if ctx (X = 1) (X = 2)).
}
If I call ctx => p X
, the rule does not see ctx
, takes the second branch, gives X
the value 2
, and when the goal is resumed the second instance of p
sees ctx
and prints 2
on the screen.
Can you explain why it was implemented like this? Thanks!
PS: I noticed that because I am using a debug
predicate triggering calls to coq.say
only when debug
is in the context, and in the CHR nothing was printed :laughing:
It is available, but is reified. Try
constraint p {
rule (C ?- p X) | (std.mem C ctx) <=> (X = 1).
rule (p X) <=> (X = 2).
}
Here a tiny bit of doc: https://github.com/LPCIC/elpi/blob/master/ELPI.md#example-of-higher-order-rules
To sum up:
prop
, you access it by writing context ?- goal
and goal
means _ ?- goal
C => g
as the new goalpi x\
, then the CHR rule runs under a set of names which is the disjoint union, and it is up to you to make sense of it, e.g. by comparing the contexts. This is explained in the doc above, but does not play a role in your exampleOr, if you really want the test to be done in the regular level (instead at the meta level of CHR):
constraint p {
rule (C ?- p X) <=> (C => if ctx (X = 1) (X = 2)).
}
but that seems less idiomatic to me
Last updated: Oct 13 2024 at 01:02 UTC