表示X的特定子集在core.logic中具有属性Y.

时间:2011-07-15 21:38:20

标签: clojure clojure-core.logic

我想:

  1. 描述关于一类对象的子集的事实。
  2. 声明对象具有包含其他属性的属性。
  3. 以下面的例子为例:

    Red robotic birds are only composed of buttons, cheese, and wire.
    

    我想表达一类鸟类,红色和机器人的鸟类,有一种属性。 这个属性是它们只由按钮,奶酪和电线组成。电线奶酪或按钮的类型没有限制。因此,应该可以推断出没有由纸构成的红色机器鸟。此外,这些鸟类可以由项目按钮,奶酪和电线的一部分组成。

    在clojure / core.logic.prelude中,使用defrelfact存在关系和事实。 但是,我无法想出一个组合来解释这个事实。

2 个答案:

答案 0 :(得分:23)

在Prolog中,与miniKanren中的事实和目标没有区别。我将来可能会解决这个问题。

顺便说一句,我不确定这完全回答了你的问题 - 听听你希望运行什么类型的查询会很有帮助。

这是经过测试的代码(对于Clojure 1.3.0-beta1),因为我使用的是 ^:index 技巧,如果你将它替换为 ^ {:index true} :

(ns clojure.core.logic.so
  (:refer-clojure :exclude [==])
  (:use [clojure.core.logic]))

(defrel property* ^:index p ^:index t)

(fact property* :bird :red-robotic-bird)
(fact property* :red :red-robotic-bird)
(fact property* :robotic :red-robotic-bird)
(fact property* :tasty :cake)
(fact property* :red-robotic-bird :macaw)

(defn property [p t]
  (conde
    [(property* p t)]
    [(fresh [ps]
       (property* ps t)
       (property p ps))]))

(defrel composition* ^:index m ^:index t)

(fact composition* :buttons :red-robotic-bird)
(fact composition* :cheese :red-robotic-bird)
(fact composition* :wire :red-robotic-bird)
(fact composition* :flour :cake)

(defn composition [m t]
  (fresh [p]
    (composition* m p)
    (conde
      [(== p t)]
      [(property p t)])))

尝试一下。

(comment
  ;; what is a macaw composed of?
  (run* [q] (composition q :macaw))
  ;; (:wire :cheese :buttons)

  ;; what things include buttons in their composition?
  (run* [q] (composition :buttons q))
  ;; (:red-robotic-bird :macaw)

  ;; does a macaw include flour in its composition?
  (run* [q] (composition :flour :macaw))
  ;; ()

  ;; is a macaw a bird?
  (run* [q] (property :bird :macaw))
  ;; (_.0)

  ;; is a cake a bird?
  (run* [q] (property :bird :cake))
  ;; ()

  ;; what are the properties of a macaw?
  (run* [q] (property q :macaw))
  ;; (:red-robotic-bird :robotic :bird :red)
  )

答案 1 :(得分:4)

不完全确定这是否是您所需要的,但您可以通过创建事实的图形结构来轻松表达类具有一组属性(请参阅下面的属性列表事项以及查找属性中的属性的规则)设定)。

然后,为了表达该组属性的组成,您需要另一组组合事实和规则来发现该类的任何子属性,因此它可以由它组成。

我在下面给出了一个代码示例,以帮助解释。

property(bird, red_robotic_bird).
property(red, red_robotic_bird).
property(robot, red_robotic_bird).
property(tasty, cake).
property(red_robotic_bird, macaw).

property(Property, Thing) :-
    property(PropertySet, Thing),
    property(Property, PropertySet).


composition(buttons, red_robotic_bird).
composition(cheese, red_robotic_bird).
composition(wire, red_robotic_bird).
composition(flour, cake).
composition(Material, Thing) :-
    property(Property, Thing),
    composition(Material, Property).

示例查询

?- composition(Material, macaw).
Material = buttons ; 
Material = cheese ; 
Material = wire ; 
no

?- composition(buttons, Thing).
Thing = red_robotic_bird ;
Thing = macaw ;
no

?- composition(flour, macaw).
no

?- property(bird, macaw).
yes

?- property(bird, cake).
no

property(Property, macaw).
Property = red_robotic_bird ;
Property = bird ;
Property = red ;
Property = robot ;
no

Prolog的规则简要。

规则基本上只是事实(例如animal(cat).),以其他规则或事实为真。规则由头部和身体组成(head :- body.)。身体是最常用合取范式表达的逻辑证据(A / \ B / \ C)。 prolog中的运算符为,运算符为;(但在规则中不鼓励使用)和句点({ {1}})表示规则或事实的结束。

请注意,如果正文中的后续规则或事实失败,则prolog将回溯并要求先前规则或事实的替代答案,然后再试一次。考虑下面有点人为的例子。

share_same_colour(FruitA,FruitB): -     颜色(颜色,FruitA),     颜色(颜色,FruitB)。

如果我们执行查询.,则share_same_colour(apple, strawberry).可能会将Color返回为绿色。然而,没有绿色的草莓,所以prolog会回溯并询问苹果的其他颜色是什么。下一个答案可能是红色,第二个颜色陈述将成功,整个规则都是真的。