17

我想要:

  1. 描述关于一类对象的子集的事实。
  2. 声明一个对象具有一个由其他属性组成的属性。

以以下为例:

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

我想表达一类鸟,红色和机器人的鸟,有一个属性。这个特性是它们仅由按钮、奶酪和电线组成。线奶酪或纽扣的类型没有限制。同样因此,应该可以推断出没有由纸组成的红色机器鸟。此外,这些鸟可以由项目按钮、奶酪和电线的子集组成。

在 clojure/core.logic.prelude 中,有使用defreland的关系和事实fact。但是,我想不出一个组合来解释这个事实。

4

2 回答 2

23

在 Prolog 中,事实和目标之间没有区别,就像在 miniKanren 中那样。我将来可能会解决这个问题。

顺便说一句,我不确定这是否完全回答了您的问题 - 了解您希望运行哪些类型的查询会很有帮助。

这是经过测试的代码(对于 Clojure 1.3.0-beta1),因为我使用了^:index技巧,如果你将它换成^{:index true} ,这段代码将在 1.2.0 中运行良好:

(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)
  )
于 2011-07-16T19:16:14.930 回答
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 中的and,运算符 is ,or运算符 is ;(但在规则中不鼓励使用它),句点 ( .) 表示规则或事实的结束。

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

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

如果我们执行查询share_same_colour(apple, strawberry).,则colour(Colour, apple).可能将 Color 返回为绿色。但是,没有绿色草莓,所以 prolog 会回溯并询问苹果还有哪些其他颜色。下一个答案可能是红色,在此基础上第二个颜色语句将成功并且整个规则为真。

于 2011-07-15T22:30:46.193 回答