2015-12-12 4 views
2

Я пишущий пролог Prolog, который сравнивал бы некоторую точку (myPosition(2,2)) в декартовой системе координат с некоторой другой точкой в ​​окрестности. В результате он должен показать направление (север, восток, юг, запад), которое мы должны выбрать, чтобы добраться от myPosition(2,2) к этому моменту. Вот код моего .pl файла:Арифметические операции в заголовке статьи

myPosition(2,2). 

turn_to_east(X+1,Y) :- 
    myPosition(X,Y), 
    write('East.'). 

turn_to_west(X-1,Y) :- 
    myPosition(X,Y), 
    write('West.'). 

turn_to_north(X,Y+1) :- 
    myPosition(X,Y), 
    write('North.'). 

turn_to_south(X,Y-1) :- 
    myPosition(X,Y), 
    write('South.'). 

turn_to_the_point(X,Y) :- turn_to_east(X,Y). 
turn_to_the_point(X,Y) :- turn_to_west(X,Y). 
turn_to_the_point(X,Y) :- turn_to_north(X,Y). 
turn_to_the_point(X,Y) :- turn_to_south(X,Y). 

Затем, когда я загрузить файл на SWI-Prolog и написать:

turn_to_the_point(1,2). 

я просто:

false. 

Почему может Я получаю ответ «Запад». или любой другой?

+3

Пролог не похож на другие языки. Он не имеет функций, возвращающих значения. У этого есть предикаты, которые либо преуспевают, терпят неудачу, либо не заканчиваются (плохие).И это не делает * in-line * выражение оценки. Так что 'turn_to_west (X-1, Y)', например, не уменьшает 'X' на 1. – lurker

+2

Прежде всего, какая-то терминология: в Prolog нет * функций *, это * предикаты *. –

ответ

2

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

Существует, однако, один из способов Распад такое выражение таким образом, что оно происходит 2 из 1+1 используя (is)/2 предикат. Например:

turn_to_east(NX,Y) :- 
    myPosition(X,Y), 
    NX is X+1, 
    write('East.'). 

Учитывая запрос turn_to_east/2 с turn_to_east(1,2), NX = 1. Теперь вы получаете данные myPosition/2: X = 2 и Y = 2. Пролог делает проверку эквивалентности тем временем и видит, что Y-координата turn_to_east/2 такая же, как и у myPosition. Затем он обрушивает 2+1 на 3 и видит, что это не эквивалентно NX = 1, поэтому этот предикат терпит неудачу. Но если бы вы запросили turn_to_east(3,1), это сработало бы и, таким образом, напишет East..

Если изменить всю вашу теорию с обсуждаемым выше понятия, как:

myPosition(2,2). 

turn_to_east(NX,Y) :- 
    myPosition(X,Y), 
    NX is X+1, 
    write('East.'). 

turn_to_west(NX,Y) :- 
    myPosition(X,Y), 
    NX is X-1, 
    write('West.'). 

turn_to_north(X,NY) :- 
    myPosition(X,Y), 
    NY is Y+1, 
    write('North.'). 

turn_to_south(X,NY) :- 
    myPosition(X,Y), 
    NY is Y-1, 
    write('South.'). 

turn_to_the_point(X,Y) :- turn_to_east(X,Y). 
turn_to_the_point(X,Y) :- turn_to_west(X,Y). 
turn_to_the_point(X,Y) :- turn_to_north(X,Y). 
turn_to_the_point(X,Y) :- turn_to_south(X,Y). 

Он отвечает на запрос правильно:

?- turn_to_the_point(1,2). 
West. 
true ; 
false. 

примечание в целом является то, что предикаты лучше не бок- такие эффекты, как write/1: это не только для Prolog, почти для всех языков программирования для разделения программы на расчет и взаимодействие. Возможно, лучший способ для решения этой проблемы, это видеть направление в качестве параметра:

myPosition(2,2). 

turn_to_point(NX,Y,east) :- 
    myPosition(X,Y), 
    NX is X+1. 
turn_to_point(NX,Y,west) :- 
    myPosition(X,Y), 
    NX is X-1. 

turn_to_point(X,NY,north) :- 
    myPosition(X,Y), 
    NY is Y+1. 

turn_to_point(X,NY,south) :- 
    myPosition(X,Y), 
    NY is Y-1. 

turn_to_the_point(X,Y) :- 
    turn_to_point(X,Y,D), 
    write(D). 

В этом случае turn_to_the_point/2 предикат, очевидно, предикат взаимодействия, тогда как его turn_to_the_point/3 вариант делает вычисления.

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