Prolog Craftsmen puzzle:谓词未定义

时间:2014-01-23 19:57:33

标签: prolog puzzle

我正在努力解决SWI-Prolog中的工匠问题。事情进展不顺利。

%1. There are 5 craftsmen. A 'fierar', a 'brutar', a 'croitor', a 'gradinar' and a 'padurar' with names Fieraru, Brutaru, Croitoru, Gradinaru, Paduraru. It is known:
%a. None of the craftsmen has the name of his craft (ex: fierar \== Fieraru);
%b. Salaries are from bigger to lower (means, Fieraru has the bigest salay, Paduraru - smallest);
%c. Paduraru is not a gradinar;
%d. croitor has a bigger salary than gradinar and smaller than brutar;
%What is the name of 'padurar'?

%Prima regulă determină structura datelor: meserias(Nume,Meserie,Salariu)
regula(1,[meserias(fieraru,_,1),meserias(brutaru,_,2),meserias(croitoru,_,3),meserias(gradinaru,_,4),meserias(paduraru,_,5)]).

regula(2, Meseriasi):-
    member(meserias(_, fierar, _), Meseriasi),
    member(meserias(_, brutaru, _), Meseriasi),
    member(meserias(_, croitor, _), Meseriasi),
    member(meserias(_, gradinar, _), Meseriasi),
    member(meserias(_, padurar, _), Meseriasi).

regula(3, Meseriasi):-
    not(member(meserias(fieraru,fierar,_), Meseriasi)),
    not(member(meserias(brutaru,brutar,_), Meseriasi)),
    not(member(meserias(croitoru,croitor,_), Meseriasi)),
    not(member(meserias(gradinaru,gradinar,_), Meseriasi)),
    not(member(meserias(paduraru,padurar,_), Meseriasi)).

%Predicatul salariu_mai_mare(Meserias1,Meserias2,Lista_meseriasilor) are multe variante. El joacă rolul constituirii permutărilor posibile. 
salariu_mai_mare(P1,P2,[P1,P2,_,_,_]).
salariu_mai_mare(P1,P3,[P1,_,P3,_,_]).
salariu_mai_mare(P1,P4,[P1,_,_,P4,_]).
salariu_mai_mare(P1,P5,[P1,_,_,_,P5]).
salariu_mai_mare(P2,P3,[_,P2,P3,_,_]).
salariu_mai_mare(P2,P4,[_,P2,_,P4,_]).
salariu_mai_mare(P2,P5,[_,P2,_,_,P5]).
salariu_mai_mare(P3,P4,[_,_,P3,P4,_]).
salariu_mai_mare(P3,P5,[_,_,P3,_,P5]).
salariu_mai_mare(P4,P5,[_,_,_,P4,P5]).

regula(4,Meseriasi) :-
    salariu_mai_mare(meserias(fieraru,_,_),meserias(brutaru,_,_),Meseriasi),
    salariu_mai_mare(meserias(brutaru,_,_),meserias(croitoru,_,_),Meseriasi),
    salariu_mai_mare(meserias(croitoru,_,_),meserias(gradinaru,_,_),Meseriasi),
    salariu_mai_mare(meserias(gradinaru,_,_),meserias(paduraru,_,_),Meseriasi).

regula(5,Meseriasi) :-
    member(meserias(paduraru,X,_),Meseriasi), X \== gradinar.

regula(6,Meseriasi) :-
    salariu_mai_mare(meserias(_,croitor,_),meserias(_,gradinar,_),Meseriasi),
    salariu_mai_mare(meserias(_,brutar,_),meserias(_,croitor,_),Meseriasi).

question(Nume,Meseriasi):-
    member(meserias(Nume,padurar,_),Meseriasi).

solution(Nume, Meseriasi):-
    regula(1,Meseriasi),
    regula(2,Meseriasi),
    regula(3,Meseriasi),
    regula(4,Meseriasi),
    regula(5,Meseriasi),
    regula(6,Meseriasi),
    question(Nume,Meseriasi).

我收到了错误:

Warning: The predicates below are not defined. If these are defined
Warning: at runtime using assert/1, use :- dynamic Name/Arity.
Warning: 
Warning: question/2, which is referenced by
Warning:        file.pl:60:8: 1-st clause of solution/2

解决方案是:Gradinaru is a padurar

Meseriasi:Fieraru - > brutar,Brutaru - > croitor,Croitoru - > gradinar,Gradinaru - > padurar,Paduraru - > fierar。

1 个答案:

答案 0 :(得分:2)

实施一些工资比较要求你先用规则b将最后一个位置与所有成员的数字绑定(为什么你不对描述中的规则使用相同的名称?在Prolog中你可以使用符号)

regula(b, Meseriasi):-
    member(meserias('Fieraru', _, 5), Meseriasi),
    member(meserias('Brutaru', _, 4), Meseriasi),
...

% croitor has a biger salary than gradinar and smaller than brutar;
regula(d, Meseriasi) :-
    member(meserias(_,croitor,A),Meseriasi),
    member(meserias(_,gradinar,B),Meseriasi),
    member(meserias(_,brutar,C),Meseriasi),
    A > B, A < C.

编辑您的规则有拼写错误:

regula(2, Meseriasi):-
    member(meserias(_, fierar, _), Meseriasi),
    member(meserias(_, brutaru, _), Meseriasi),  ** here must be brutar
    member(meserias(_, croitor, _), Meseriasi),
...