2016-04-08 8 views
1

mag ich [:b :B] von [[:a :A] [:b :B] [:c :C]] im folgenden Beispiel-Code entfernen, und wenn ich :B mit (lvar) ersetzen, es funktioniert nicht mehr:Wie kann ich [: b (lvar)] aus [[: a: A] [: b: B] [: c: C]] in Clojure core.logic entfernen?

;; Helper Function 
(defne not-membero [x l] 
    ([_ []]) 
    ([_ [?y . ?r]] 
    (!= x ?y) 
    (not-membero x ?r))) 

Diese Arbeit:

(run* [q] 
    (membero q [[:a :A] [:b :B] [:c :C]]) 
    (not-membero q [[:b :B]])) 
(run* [q] 
    (membero q [[:a :A] [:b :B] [:c :C]]) 
    (!= q [:b :B])) 
;; both return [[:a :A] [:c :C]], as expected 

Diese nicht (Bekanntmachung der lvar):

(run* [q] 
    (membero q [[:a :A] [:b :B] [:c :C]]) 
    (not-membero q [[:b (lvar)]])) 
(run* [q] 
    (membero q [[:a :A] [:b :B] [:c :C]]) 
    (!= q [:b (lvar)])) 
;; both return [[:a :A] [:b :B] [:c :C]], unexpected 

Antwort

0

ich glaube, der Grund, warum dieses doesn‘ In Ihrem Beispiel funktioniert das, dass die erzeugte (lvar) nicht gebunden ist oder keine Beziehung zu einer anderen Logikvariablen im Programm hat. Ihr Programm funktioniert gut (zumindest ich denke, das ist, was Sie wollten), wenn Sie eine fresh logische Variable verwenden:

(run* [q] 
    (fresh [x] 
    (membero q [[:a :A] [:b x] [:c :C]]) 
    (not-membero q [[:b x]]))) 
=> ([:a :A] [:c :C]) 
(run* [q] 
    (fresh [x] 
    (membero q [[:a :A] [:b x] [:c :C]]) 
    (!= q [:b x]))) 
=> ([:a :A] [:c :C]) 

Alternativ diese das gleiche Ergebnis ohne Kenntnis des :b Element in dem Tupel zurück:

(run* [q] 
    (fresh [x] 
    (membero q [[:a :A] x [:c :C]]) 
    (not-membero q [x]))) 
(run* [q] 
    (fresh [x] 
    (membero q [[:a :A] x [:c :C]]) 
    (!= q x)))