2016-04-16 42 views
1

假設我們定義通過下表的關係matches使用core.logic做一個簡單的匹配功能

|-----+-----+-----+-----+-----| 
|  | *A* | *B* | *C* | *D* | 
|-----+-----+-----+-----+-----| 
| *A* |  | X | X |  | 
|-----+-----+-----+-----+-----| 
| *B* | X |  |  | X | 
|-----+-----+-----+-----+-----| 
| *C* | X |  |  |  | 
|-----+-----+-----+-----+-----| 
| *D* |  | X |  |  | 
|-----+-----+-----+-----+-----| 

通過這種方式,它是指(在pseduo代碼)

(matches A) ;=> (B C) 
(matches B) ;=> (A D) 
(matches C) ;=> (C) 
(matches D) ;=> (B) 

在core.logic中,我想我會知道如何製作個性化功能,它可以近似matches的行爲:

(defn matches-A 
    (run* [q] 
    (membero q [B C]))) ;=> (B C) 

...等等matches-Bmatches-C

問題:我怎麼能概括,即matches-A如上所述的單一功能matches?特別是,我希望使它能夠運行如(matches "not A"),(matches "B and C")(matches "C or D")(以僞代碼形式)的查詢,以分別獲得結果,如(A D),(A)(A B)。這可能嗎?

注:我使用clojurescript而不是clojure。我不確定這是否會影響答案。

回答

2

您可以使用conde來解決這個任務:

(ns qradv.welcome 
    (:require [cljs.core.logic :as l])) 

;; |-----+-----+-----+-----+-----| 
;; |  | *A* | *B* | *C* | *D* | 
;; |-----+-----+-----+-----+-----| 
;; | *A* |  | X | X |  | 
;; |-----+-----+-----+-----+-----| 
;; | *B* | X |  |  | X | 
;; |-----+-----+-----+-----+-----| 
;; | *C* | X |  |  |  | 
;; |-----+-----+-----+-----+-----| 
;; | *D* |  | X |  |  | 
;; |-----+-----+-----+-----+-----| 
(defn matches [x] 
    (l/run* [y] 
    (l/conde 
     [(l/== x "A") (l/membero y ["B" "C"])] 
     [(l/== x "B") (l/membero y ["A" "D"])] 
     [(l/== x "C") (l/membero y ["C"])] 
     [(l/== x "D") (l/membero y ["B"])]))) 

(prn (matches "A")) 
(prn (matches "B")) 
(prn (matches "C")) 
(prn (matches "D")) 

輸出:

("B" "C") 
("A" "D") 
("C") 
("B") 
+0

有沒有一種方法嵌入邏輯論證這個功能(如 「A和B」 或「不是C 「等等)? – George

+0

@George我不確定你想用'not C'。你可以添加例子來描述表格嗎? – edbond

+0

好點 - 含義模糊。 By - 即 - 「not C」我的意思是「(B C D)」。也就是說,我的意思是與C相匹配的補碼(而不是與C的補碼相匹配的補集)。 – George