我刚刚开始使用core.logic,为了解决它,我正在尝试实现一些简单的东西,类似于我目前正在专业解决的一个问题。然而,问题的一部分让我感到困惑……
作为我的示例的简化,如果我有一个商品目录,其中一些仅在某些国家可用,而另一些在特定国家不可用。我希望能够指定项目列表和例外,如下所示:
(defrel items Name Color)
(defrel restricted-to Country Name)
(defrel not-allowed-in Country Name)
(facts items [['Purse 'Blue]
['Car 'Red]
['Banana 'Yellow]])
(facts restricted-to [['US 'Car]])
(facts not-allowed-in [['UK 'Banana]
['France 'Purse]])
如果可能,我不希望为所有国家指定允许进入,因为具有限制的项目集相对较小,并且我希望能够对给定国家/地区的项目进行允许/排除。
如何编写一个规则来给出一个国家/地区的项目/颜色列表,并且有以下限制:
有什么方法可以做到这一点吗?我想事情的方式是完全错误的吗?
发布于 2012-01-04 05:37:23
通常,当您开始否定逻辑编程中的目标时,您需要达到非关系操作( Prolog中的cut,core.logic中的conda )。
只能使用地面参数调用此解决方案。
(defn get-items-colors-for-country [country]
(run* [q]
(fresh [item-name item-color not-country]
(== q [item-name item-color])
(items item-name item-color)
(!= country not-country)
(conda
[(restricted-to country item-name)
(conda
[(not-allowed-in country item-name)
fail]
[succeed])]
[(restricted-to not-country item-name)
fail]
;; No entry in restricted-to for item-name
[(not-allowed-in country item-name)
fail]
[succeed]))))
(get-items-colors-for-country 'US)
;=> ([Purse Blue] [Banana Yellow] [Car Red])
(get-items-colors-for-country 'UK)
;=> ([Purse Blue])
(get-items-colors-for-country 'France)
;=> ([Banana Yellow])
(get-items-colors-for-country 'Australia)
;=> ([Purse Blue] [Banana Yellow])
发布于 2014-01-20 08:36:13
Conda可能会使代码复杂化,使用nafc,你可以更容易地重新排序目标,如果你想的话。这仍然是非关系型的!:)
(ns somenamespace
(:refer-clojure :exclude [==])
(:use [clojure.core.logic][clojure.core.logic.pldb]))
(db-rel items Name Color)
(db-rel restricted-to Country Name)
(db-rel not-allowed-in Country Name)
(def stackoverflow-db
(db [items 'Purse 'Blue]
[items 'Car 'Red]
[items 'Banana 'Yellow]
[restricted-to 'US 'Car]
[not-allowed-in 'UK 'Banana]
[not-allowed-in 'France 'Purse]))
(defn get-items-colors-for-country [country]
(with-db stackoverflow-db
(run* [it co]
(items it co)
(nafc not-allowed-in country it)
(conde
[(restricted-to country it)]
[(nafc #(fresh [not-c] (restricted-to not-c %)) it)]))))
(get-items-colors-for-country 'US)
;=> ([Purse Blue] [Banana Yellow] [Car Red])
(get-items-colors-for-country 'UK)
;=> ([Purse Blue])
(get-items-colors-for-country 'France)
;=> ([Banana Yellow])
(get-items-colors-for-country 'Australia)
;=> ([Purse Blue] [Banana Yellow])
https://stackoverflow.com/questions/8705001
复制相似问题