Выражая, что определенное подмножество X имеет свойство Y в core.logic - PullRequest
17 голосов
/ 16 июля 2011

Я хочу:

  1. Опишите факт о подмножестве класса объектов.
  2. Объявите, что у объекта есть свойство, состоящее из других свойств.

В качестве примера возьмем следующее:

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

Я хочу выразить, что у класса птиц, птиц красных и роботизированных, есть свойство. Это свойство состоит в том, что они состоят только из кнопок, сыра и проволоки. Нет ограничений по типу проволочного сыра или пуговиц. Также в результате следует сделать вывод, что нет красных птиц-роботов, которые состоят из бумаги. Также эти птицы могут состоять из подмножества предметов кнопок, сыра и проволоки.

В clojure / core.logic.prelude есть отношения и факты, использующие defrel и fact. Однако я не могу придумать комбинацию, чтобы объяснить этот факт.

Ответы [ 2 ]

23 голосов
/ 16 июля 2011

В Прологе нет различия между фактами и целями, как в miniKanren.Я мог бы решить эту проблему в будущем.

Кстати, я не уверен, что это полностью отвечает на ваш вопрос - было бы полезно узнать, какие типы запросов вы хотите выполнить.

Этоэто проверенный код (для Clojure 1.3.0-бета1), так как я использую трюк ^: index , этот код будет нормально работать в 1.2.0, если вы поменяете его на ^ {: indextrue} :

(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)
  )
4 голосов
/ 16 июля 2011

Не совсем уверен, что это то, что вам нужно, но вы можете легко выразить, что у класса есть набор свойств, создав структуру фактов графа (см. Список фактов свойств ниже и правило для нахождения свойств внутриset).

Затем, чтобы выразить композицию этого набора свойств, вам понадобится еще один набор фактов композиции и правило, которое обнаруживает любые подсвойства класса и, в результате, вещи, из которых он может состоять.

Я также привел приведенный ниже пример кода, чтобы помочь объяснить.

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

Коротко о правилах Пролога.

Правила - это, по сути, просто факты (например, animal(cat).), которые обусловлены правдивостью других правил или фактов.Правило состоит из головы и тела (head :- body.).Тело - это логическое доказательство, чаще всего выражаемое в конъюнктивной нормальной форме (A / \ B / \ C).Оператор и в прологе равен ,, оператор или равен ; (но его использование не рекомендуется в правилах), а точка (.) обозначает конецправила или факта.

Обратите внимание, что в случае сбоя более позднего правила или факта в теле пролог откатывается назад и запрашивает альтернативный ответ из предыдущего правила или факта, а затем повторяет попытку.Рассмотрим несколько надуманный пример ниже.

share_same_colour (FruitA, FruitB): - color (Color, FruitA), color (Color, FruitB).

Если мы выполним запрос share_same_colour(apple, strawberry)., тогдаcolour(Colour, apple). может вернуть цвет как зеленый.Тем не менее, нет зеленой клубники, поэтому пролог вернется и спросит, какие еще цвета имеют яблоки. Следующий ответ может быть красным, после чего второе утверждение цвета будет успешным, и все правило будет верным.

...