假设我们通过下表定义了一个关系matches
:
|-----+-----+-----+-----+-----|
| | *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-B
和matches-C
。
问题:如何将matches-A
概括为如上所述的单个函数matches
?特别是,我有兴趣制作它,以便您可以运行(matches "not A")
,(matches "B and C")
和(matches "C or D")
(在伪代码中)等查询来获取(A D)
之类的结果,(A)
和(A B)
。这可能吗?
注意:我正在使用clojurescript而不是clojure。我不确定这是否会对答案产生影响。
答案 0 :(得分: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")