ответ Joel76 дает то, что, вероятно, на сегодняшний день является наиболее распространенным использованием в ->/2
управления конструкцией, которая определяется в ISO Prolog. Приведенная для Goal1 -> Goal2
в GNU Prolog manual является:
Goal1 -> Goal2
первыми выполняет Goal1
и, в случае успеха, снимают все отборные-точки, созданные Goal1
и выполняет Goal2
. Эта контрольная конструкция действует как if-then (Goal1
- тестовая часть и Goal2
тогдашняя часть). Обратите внимание, что если Goal1
не удается выполнить ->/2
. ->/2
часто сочетается с ;/2
, чтобы определить if-then-else следующим образом: Goal1 -> Goal2 ; Goal3
. Обратите внимание, что Goal1 -> Goal2
является первым аргументом (;)/2
и Goal3
(часть else) является вторым аргументом. Такая конструкция управления if-then-else сначала создает точку выбора для else-part (интуитивно ассоциированную с ;/2
), а затем выполняет Goal1
. В случае успеха все точки выбора, созданные Goal1
вместе с точкой выбора для else-части, удаляются и выполняется Goal2
. Если Goal1
не работает, то выполняется Goal3
.
Это не действует подобно математической логической импликации (как его символической формой можно предположить), так как, в таком пункте импликации, F -> T
верно, тогда как в Прологе, как уже упоминалось выше, если Goal1
терпит неудачу, то выражение ->/2
не выполняется.
Важно отметить приоритет оператора в этом случае. В Prolog порядок приоритета: ,
, затем ->
, затем ;
. Таким образом, как указано в описании, в конструкции if-then-else, Goal1 -> Goal2 ; Goal3
, выражение Goal1 -> Goal2
является первым аргументом ;/2
.Вот что происходит в различных случаях:
Goal1 -> Goal2 ; Goal3 if-then-else Notes
----- ----- ----- ------------ -----
Succeeds Succeeds NE* Succeeds Goal1 choice point removed
Goal2 choice point remains (if it exists)
Succeeds Fails NE Fails Goal1 choice point removed
Fails NE Succeeds Succeeds Goal3 choice point remains (if it exists)
Fails NE Fails Fails
*NE = not executed
Из-за старшинства, то если-то-иначе конструкции часто круглые скобки, как в примере:
(selectchk(passwd(User, _, _), Data, Entry, NewData)
-> true
; append(Data, [Entry], NewData)
),
blah-blah
Если круглые скобки не были там, то blah-blah
станет частью еще и не будет выполнен, если selectchk
удастся.
Существует также кое-что интересное, что происходит с точками выбора. Если Goal1
преуспеет, Prolog вызовет Goal2
и т. Д., Но не вернется к большему количеству решений, если они существуют, для Goal1
. Для иллюстрации:
a(1).
a(2).
test :-
( a(X)
-> write(X), nl
; write('no a'), nl
).
| ?- test.
1
yes
В вышеприведенном Пролог не вернулся, чтобы найти X = 2
для a(X)
. С другой стороны, откат может произойти за else
:
foo :-
( false
-> write('not gonna happen'), nl
; a(X),
write(X), nl
).
| ?- foo.
1
true ? ;
2
yes
Откат происходит также за Goal2
:
foo :-
( true
-> a(X), write(X), nl
; write('else'), nl
).
| ?- foo.
1
true ? ;
2
yes
Но как вы можете видеть, как только будет выбран Goal2
путь, нет никаких возвратов к else
(Goal3
), когда растворы для Goal2
исчерпаны. Ожидается, что исполнения Goal2
по сравнению с Goal3
являются взаимоисключающими в зависимости от результата Goal1
.