2014-01-23 3 views
1

SWI-Prolog에서 craftsmen puzle을 해결하려고합니다. 상황이 좋지 않습니다.Prolog Craftsmen puzzle : 술어가 정의되지 않았습니다.

%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.

메 세리아시 : 피에르 루 - 브루 타르, 브루 타루 -> 크로 터, 크로 토루 - 그라디안, 그라디나누 -> 패 두르, 파 두루 -> 피 에르.

+0

당신은) 마지막으로 여기 쉼표'salariu_mai_mare (meserias (_, brutar, _), meserias (_, croitor, _에서 오타가 Meseriasi), "점으로 대체하십시오 – CapelliC

+0

보다 ks @ CapelliC. 이제는 오류가 발생하지 않습니다. 그러나 나는'해결책 (Name, Meseriasi). '을 물을 때 나는 틀렸다. 이 프로그램을 올바르게 작동시키는 방법? – SpartakusMd

+0

반드시 급여에 대한 비교를 실시해야합니다. 나는 올바른 방법을 볼 수 없다. – CapelliC

답변

2

을 (당신은? 설명에서 규칙에 같은 이름을 사용하지 않는 프롤로그에서는이 기호를 사용할 수 있습니다 이유) 먼저 규칙 b로, 모든 회원 번호와 마지막 위치를 바인딩 할 필요 일부 급여 비교를 구현 당신이 오타으로 규칙이
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), 
... 
+0

'regula (b, Meseriasi)'에 실수가 있습니다. Fieraru (naeme'Fieraru'를 가진 사람)는 가장 큰 salay를 가지고 있는데, Paduraru (가장 가까운 사람은 Padroaru). – SpartakusMd

+0

맞아요, 답을 수정했습니다. – CapelliC

+0

글쎄,'regula (1, ..)'에서 저는이 아이디어를 사용합니다. 그러나 숫자는 역순입니다. 그것은 말이되지 않습니다. – SpartakusMd