Проблема зебри.

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]),