3

I'm trying to implement the opposite of membero in clojure.core.logic, but it's returning two values instead of one. Otherwise, it works fine (returns nothing when the value is in the list, and something when it is not).

(defne nonmembero
  "A relation where l is a collection, such that l does not contain x"
  [x l]
  ([_ ()])
  ([_ [head]]
     (!= x head))
  ([_ [head . tail]]
     (!= x head)
     (nonmembero x tail)))

Example runs:

user> (run* [x] (nonmembero 1 [2 3 4 5]))
(_0 _0)
user> (run* [x] (nonmembero 1 [2 3 1 4 5]))
()

2 Answers 2

3

You don't need the second pattern i.e the [_ [head]. This is causing a new branch in search space of core.logic engine and hence leads to the 2 output. The last pattern i.e [head . tail] is enough to handle the case where you have only one element in the list. Now your solution becomes:

(defne nonmembero
  "A relation where l is a collection, such that l does not contain x"
  [x l]
  ([_ ()])
  ([_ [head . tail]]
     (!= x head)
     (nonmembero x tail)))
Sign up to request clarification or add additional context in comments.

Comments

0

Something is wrong with the code above. It finds a solution for the following

(run* [q](== q 1)(nonmembero q [1 2 3]))  =>  (1)

The following gives the expected result

(run* [q](== q 1)(nonmembero2 q [1 2 3]))  => ()

where nonmembero2 is

(defn nonmembero2
  [x l]
  (fresh [h t]
    (conde
      [(== l ())]
      [(conso h t l)
       (!= x h)
       (nonmembero2 x t)])))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.