首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在core.logic中模拟“外部连接”?

如何在core.logic中模拟“外部连接”?
EN

Stack Overflow用户
提问于 2012-01-03 04:25:34
回答 2查看 1K关注 0票数 16

我刚刚开始使用core.logic,为了解决它,我正在尝试实现一些简单的东西,类似于我目前正在专业解决的一个问题。然而,问题的一部分让我感到困惑……

作为我的示例的简化,如果我有一个商品目录,其中一些仅在某些国家可用,而另一些在特定国家不可用。我希望能够指定项目列表和例外,如下所示:

代码语言:javascript
运行
复制
(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]])

如果可能,我不希望为所有国家指定允许进入,因为具有限制的项目集相对较小,并且我希望能够对给定国家/地区的项目进行允许/排除。

如何编写一个规则来给出一个国家/地区的项目/颜色列表,并且有以下限制:

  • 项目必须在项目列表中
  • 国家/项目不能在“不允许进入”列表
  • 中也不能:
    • 该项目的限制范围列表中没有国家/地区
    • 国家/项目对在限制范围内

有什么方法可以做到这一点吗?我想事情的方式是完全错误的吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-04 05:37:23

通常,当您开始否定逻辑编程中的目标时,您需要达到非关系操作( Prolog中的cut,core.logic中的conda )。

只能使用地面参数调用此解决方案。

代码语言:javascript
运行
复制
(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])

Full solution

票数 14
EN

Stack Overflow用户

发布于 2014-01-20 08:36:13

Conda可能会使代码复杂化,使用nafc,你可以更容易地重新排序目标,如果你想的话。这仍然是非关系型的!:)

代码语言:javascript
运行
复制
(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://gist.github.com/ahoy-jon/cd0f025276234de464d5

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8705001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档