我想:
以下面的例子为例:
Red robotic birds are only composed of buttons, cheese, and wire.
我想表达一类鸟类,红色和机器人的鸟类,有一种属性。 这个属性是它们只由按钮,奶酪和电线组成。电线奶酪或按钮的类型没有限制。因此,应该可以推断出没有由纸构成的红色机器鸟。此外,这些鸟类可以由项目按钮,奶酪和电线的一部分组成。
在clojure / core.logic.prelude中,使用defrel
和fact
存在关系和事实。
但是,我无法想出一个组合来解释这个事实。
答案 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会回溯并询问苹果的其他颜色是什么。下一个答案可能是红色,第二个颜色陈述将成功,整个规则都是真的。