Проблема зебри.
Ogr1(A,D,B,V,G),ogr2(A,D,B,V,G).
Not(norm3(A,D,B,V,G)),not(norm4(A,D,B,V,G)),
Not(norm1(A,D,B,V,G)),not(norm2(A,D,B,V,G)),
St_A(A),st_D(D),st_B(B),st_V(V),st_G(G),
St_A(A),st_D(D),st_B(B),st_V(V),st_G(G),
St_A(A),st_D(D),st_B(B),st_V(V),st_G(G),
St_A(A),st_D(D),st_B(B),st_V(V),st_G(G),
Norm3(_,dmitri,net,net,_). norm4(_,net,net,victor,grig).
Norm1(andre,dmitri,net,_,_). norm2(andre,net,boris,net,_).
Ogr2(_,dmitri,_,_,net). ogr2(_,net,_,_,_).
Ogr1(andre,_,_,net,_). ogr1(net,_,_,victor,_).
Norm3(s,s,s,s,s) norm4(s,s,s,s,s)
Norm1(s,s,s,s,s) norm2(s,s,s,s,s)
Spisok(s,s,s,s,s)
Ogr1(s,s,s,s,s) ogr2(s,s,s,s,s)
St_A(s) st_D(s) st_B(s) st_V(s) st_G(s)
CLAUSES
st_A(A):-A=andre; A=net.
st_D(D):-D=dmitri; D=net.
st_B(B):-B=boris; B=net.
st_V(V):-V=victor; V=net.
st_G(G):-G=grig; G=net.
spisok(A,D,B,V,G):-st_A(A),st_D(D),st_B(B),st_V(V),st_G(G),
norm1(A,D,B,V,G),ogr1(A,D,B,V,G),ogr2(A,D,B,V,G);
norm2(A,D,B,V,G),ogr1(A,D,B,V,G),ogr2(A,D,B,V,G);
norm3(A,D,B,V,G),ogr1(A,D,B,V,G),ogr2(A,D,B,V,G);
norm4(A,D,B,V,G),ogr1(A,D,B,V,G),ogr2(A,D,B,V,G);
Можливо, може бути сформульоване більш витончене програмне рішення, чим наведене. При його пошуку можна переконатись, що в подібних випадках дуже велике значення має вибір предикатів і правил, які можуть визначатися по-різному. При невдалому виборі правил можна одержати невірні рішення або вичерпати ресурси комп'ютера вкладеними викликами правил.
10. Проблема мешканців острова
Постановка задачі. На деякому острові живуть:
§ "лицарі", які завжди горять правду,
§ "брехуни", які завжди брешуть, і
§ нормальні люди, які іноді брешуть, іноді говорять правду.
Троє мешканців острова А, В і С, серед яких є лицар, брехун і нормальна людина, висловлюють наступні твердження:
1) А каже: "Я нормальна людина".
2) В каже: "Це правда".
3) С каже: "Я не нормальна людина".
Хто ж такі А, В і С?
men(M):- M="knіght"; M="lear"; M="normal". % лицар,
брехун, нормальна людина
people(A,B,C):-men(A),men(B),A=\=B,men(C),A=\=C,B=\=C.
say1(A):- A="normal".
say3(C):- C=\="normal".
checkА(A):-A="knіght",say1(A);A="lear",not(say1(A));
A="normal".
checkВ(A,B):-B="knіght",say1(A);B="lear",not(say1(A));
B="normal".
checkС(C):-C="knіght",say3(C); C="lear", not(say3(C));
C="normal".
check(A,B,C):-рeopl(A,B,C),checkА(A),checkВ(A,B),checkС(C).
goal
?-check(A,B,C),wrіte([A,B,C]).
Відповідь:
[lear,normal,knіght]
Постановка задачі. П'ять людей різної національності живуть у п'ятьох перших будинках однієї з вулиць. Вони є представниками п'яти різних професій, і в кожного є свої улюблені напої й тварини, серед яких нема повторюваних. Дома, у яких вони живуть, пофарбовані в різні кольори. Відомо, що:
· англієць живе в червоному будинку;
· в іспанця є собака;
· японець є художником;
· італієць п'є чай;
· норвежець живе в першому будинку ліворуч;
· власник зеленого будинку п'є каву;
· зелений будинок розташований праворуч від білого;
· скульптор розводить равликів;
· дипломат живе в жовтому будинку;
· у будинку посередині п'ють молоко;
· норвежець живе поруч із блакитним будинком;
· скрипаль п'є фруктові соки;
· лиса тримають у будинку, сусідньому з будинком лікаря;
· коня тримають по сусідству з будинком дипломата.
Необхідно визначити, хто тримає зебру, і хто п'є воду.
Рішення Generate-and-Test
Стан задачі:
L = [Colours,Drinks,Nationalities,Professions,Pets]
Colours = [ blue:1, yellow:2, …]
…
solve([Colours,Drinks,Nationalities,Professions,Pets]) :-
generate([Colours,Drinks,Nationalities,Professions,Pets]),