2017-02-09 9 views
0

мне нужно написать правило, которое рекурсивно определяет, когда объект находится выше другого объекта, основанный на объектах в этой картинерекурсивно определить позиции объекта, как «выше» Прологе

enter image description here

Например ?- above(scissors, clock). должен вернуться правда

это то, что я до сих пор

adjacent_left(clock, rocket). 
adjacent_left(rocket, guitar). 
adjacent_left(guitar, telephone). 

on_top_of(paperclip, clock). 
on_top_of(scissors, guitar). 

adjacent_right(rocket, clock). 
adjacent_right(guitar, rocket). 
adjacent_right(telephone, guitar). 

underneath(clock, paperclip). 
underneath(guitar, scissors). 

right_of(Obj1, Obj2):- 
    adjacent_right(Obj1, Obj2). 

right_of(Obj1, Obj3):- 
    adjacent_right(Obj1, Obj2), 
    right_of(Obj2, Obj3). 

above(Obj1, Obj2):- 
    on_top_of(Obj1, Obj2). 

above(Obj1, Obj3):- 
    on_top_of(Obj1, Obj2), 
    above(Obj2, Obj3). 
+5

У вас не должно быть этих фактов для 'местного/2' и 'под/2', потому что, если вы хотите добавить/удалить факты' смежный_left/2' или 'on_top_of/2', вам также нужно добавить/удалить предыдущие два, что может привести к некогерентности в ваших фактах. Вместо этого просто напишите правила: 'соседний_right (X, Y): - смежный_left (Y, X).' И 'под (X, Y): - on_top_of (Y, X) .'. – Fatalize

ответ

3

Сначала я бы определил left_of/2 так же, как вы определили right_of/2.

Тогда на изображении есть два случая. Первое, что у вас есть: объект находится над другим объектом, если он находится поверх него. Второй случай - объект1 над другим объектом2, если объект2 находится на том же уровне, что и объект, над которым объект1 выше. Если у вас более двух уровней, вам нужен третий случай, который у вас уже есть: объект1 находится над другим объектом3, если объект 1 находится поверх объекта2, который находится над объектом3.

Существует два случая, когда объект находится на одном уровне. Либо его left_of, либо right_of.

Итак:

adjacent_left(clock, rocket). 
adjacent_left(rocket, guitar). 
adjacent_left(guitar, telephone). 

on_top_of(paperclip, clock). 
on_top_of(scissors, guitar). 

adjacent_right(rocket, clock). 
adjacent_right(guitar, rocket). 
adjacent_right(telephone, guitar). 

underneath(clock, paperclip). 
underneath(guitar, scissors). 

right_of(Obj1, Obj2):- 
    adjacent_right(Obj1, Obj2). 

right_of(Obj1, Obj3):- 
    adjacent_right(Obj1, Obj2), 
    right_of(Obj2, Obj3). 

left_of(Obj1,Obj2):- 
    adjacent_left(Obj1,Obj2). 
left_of(Obj1,Obj3):- 
    adjacent_left(Obj1,Obj2), 
    left_of(Obj2,Obj3). 

same_level(Obj1,Obj2):- 
    left_of(Obj1,Obj2). 
same_level(Obj1,Obj2):- 
    right_of(Obj1,Obj2). 

above(Obj1, Obj2):- 
    on_top_of(Obj1, Obj2). 
above(Obj1, Obj3):- 
    on_top_of(Obj1, Obj2), 
    above(Obj2, Obj3). 
above(Obj1,Obj3):- 
    on_top_of(Obj1,Obj2), 
    same_level(Obj2,Obj3). 

Я также рекомендовал бы переименовать предикаты пойти с аргументами. Таким образом, выше/ниже/2 вместо выше/2, например.

0

Во-первых, полезно, чтобы ваши отдельные элементы были перечислены в вашей базе данных фактов, так как это позволяет сделать более простую конструкцию предложений (но это только личные предпочтения).

item(clock). 
item(rocket). 
item(guitar). 
item(telephone). 
item(scissors). 
item(paperclip). 

Тогда, я бы удалить избыточность некоторых из ваших статей

adjacent_left(clock, rocket). 
adjacent_left(rocket, guitar). 
adjacent_left(guitar, telephone). 

on_top_of(paperclip, clock). 
on_top_of(scissors, guitar). 

adjacent_right(X, Y) :- adjacent_left(Y, X). 

underneath(X, Y) :- on_top_of(Y, X). 

left_of(X, Y) :- adjacent_left(X, Y), !. 
left_of(X, Z) :- adjacent_left(X, Y), left_of(Y, Z). 

right_of(X, Y) :- left_of(Y, X). 

и определить вспомогательный предикат

siblings(X, Y) :- left_of(X, Y), !. 
siblings(X, Y) :- left_of(Y, X). 

Тогда выше соотношение

above(X, Y) :- above(X, Y, []). 

above(X, Y, Acc) :- on_top_of(X, Y), !. 
above(X, Z, Acc) :- on_top_of(X, Y), above(Y, Z, Acc), !. 
above(X, Z, Acc) :- item(Y), siblings(Y, Z), not(member(Y,Acc)), above(X, Y, [Z|Acc]), !. 

Модель аккумулятора необходимо, чтобы избежать круговой логики «проверить, является ли a родственным братом b, а затем проверить, является ли b братом a и т. д. ad infinitum).

 Смежные вопросы

  • Нет связанных вопросов^_^