Welcome! Please see the About page for a little more info on how this works.

0 votes
in core.logic by

The negation as failure constraint {{nafc}} is supposed to succeed if and only if the goal provided by a relation and its args fails. The test cases just cover very simple cases like {{(nafc == q 'b)}} which is essentially equivalent to (!= q 'b) (at least to my understanding). But with a slightly more complex case, it doesn't seem to work anymore.

Example:

`
(run* [q]
(fresh [a b]

(== q (list a b))
(fd/in a b (fd/interval 1 3)) ;; fd is an alias for clojure.core.logic.fd
(fd/< a b)
(nafc membero 2 q)))

;=> ((1 2) (2 3) (1 3))
`

The constraint specifies that the number 2 must NOT be contained in the list {{q}} but still it is. I expected to get the single answer {{(1 3)}} here.

4 Answers

0 votes
by

Comment made by: tsdh

It seems that this problem could be specific to {{clojure.core.logic.fd}}. At least this example works:

`
(defn answero [x]
(conde
[(== x :yes)]
[(== x :no)]
[(== x :maybe)]
[(== x :dont-know)]))

(run* [q]
(fresh [a b]

(== q (list a b))
(everyg answero q)
(nafc membero :maybe q)
(nafc membero :dont-know q)))

;=> ((:yes :yes) (:yes :no) (:no :yes) (:no :no))
`

0 votes
by

Comment made by: nberger

This is not a bug. It's expected behavior because not all arguments to the nafc goal are ground.

From nafc docstring:

bq. EXPERIMENTAL: negation as failure constraint. All arguments to the goal c must be ground. If some argument is not ground the execution of this constraint will be delayed.

In the example using fd, q is not ground (because a and b are not ground), so it's almost the same as if the nafc wasn't there.

0 votes
by

Comment made by: tsdh

My interpretation of the docstring is that the check will be delayed until the point in time where the variables become ground. And eventually {{q}} is ground in my first example. I mean, otherwise {{nafc}} would be pretty useless.

0 votes
by
...