1

假设我们matches通过下表定义一个关系:

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

这意味着(在伪代码中)

(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。我不确定这是否会影响答案。

4

1 回答 1

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")
于 2016-04-16T18:13:35.917 回答