2013-05-04 4 views
2

membero의 반대쪽을 clojure.core.logic에 구현하려고하는데, 하나 대신 2 개의 값이 반환됩니다. 그렇지 않으면 잘 작동합니다 (값이 목록에 있으면 아무 것도 반환하지 않습니다).왜 내 clojure.core.logic 비회원 함수가 두 개의 값을 반환합니까?

(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))) 

예 실행 :

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

답변

2

당신은 [_ [head] 즉 두 번째 패턴을 필요가 없습니다. 이로 인해 core.logic 엔진의 검색 공간에 새로운 분기가 생기므로 2 출력으로 연결됩니다. 마지막 패턴 (예 : [head . tail])으로 목록에 하나의 요소 만있는 경우를 처리 할 수 ​​있습니다. 이제 솔루션은 다음과 같습니다.

(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))) 
0

위의 코드에 문제가 있습니다. 그것은 다음과 같은

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

다음에 대한 해결책이 예상 된 결과를 제공 발견 nonmembero2이

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

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