2015-03-14 2 views
0

Я заметил использование оператора -> в некоторых программах Prolog, но его значение мне неизвестно. Это пример его использования:В чем смысл оператора Prolog '->'

swish_add_user(User, Passwd, Fields) :- 
    phrase("$1$", E, _), % use Unix MD5 hashes 
    crypt(Passwd, E), 
    string_codes(Hash, E), 
    Entry = passwd(User, Hash, Fields), 
    absolute_file_name(swish(passwd), File, 
    [access(write)]), 
    (exists_file(File) 
    -> http_read_passwd_file(File, Data) 
    ; Data = [] 
    ), 
    (selectchk(passwd(User, _, _), Data, Entry, NewData) 
    -> true 
    ; append(Data, [Entry], NewData) 
    ), 
    http_write_passwd_file(File, NewData). 

Что является его использование в этой статье? Когда я должен использовать этот оператор, а когда нет?

PS: Сегмент кода берется из файла authenticate.pl в репозитории swish, отличная реализация Prolog IDE online, между прочим.

ответ

1

ответ 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.

2

Это если/то/другое в Прологе, например

(X mod 2 =:= 0 
-> writeln(even) 
; writeln(odd)).