2015-04-27 4 views
0

Я работаю над программой, которая проверяет, может ли человек стать гражданином или нет. Когда человек в базе данных передается, он должен возвращать все причины, по которым они делают или не квалифицируются. Моя проблема заключается в том, что, чтобы показать все причины, я использую неспособность отступить и найти другие причины, это делает ложным возвращение, когда это должно быть правдой.Проблемы с ошибкой и возвратом

born(frank,usa,1944). 
child(frank,mary,jack). 
child(mary,sean,ruth). 
born(fiona,usa,1920). 
child(fiona,sean,ruth). 

citizen(X):- born(X,'irl',_). 
natcitizen(X):-naturalized(X,_). 
marriedirl(X):-married(X,Y,_),born(Y,'irl',_). 
adoptedirl(X):-adopted(X,P1,P2),born(P1,'irl',_),born(P2,'irl',_). 
irlparent(X):-child(X,P1,P2),(born(P1,'irl',_);born(P2,'irl',_)). 
irlgrandparent(X):- child(X,P1,P2),(child(P1,G1,G2),(born(G1,'irl',_);born(G2,'irl',_));child(P2,G3,G4),(born(G3,'irl',_);born(G4,'irl',_))). 
permres5(X):-(permres(X,Start,End),born(X,_,B),A is B, [email protected]>=18,End==2015,N is End-Start,([email protected]>=5)). 


qualify(X):- \+(citizen(X) ->write(X) ->write_ln(' is already an irish born citizen')), \+ (natcitizen(X) ->write(X) ->write(' is already a naturalized Irish citizen')), 
(marriedirl(X)->write(X) ->write_ln(' qualifies: he/she is married to an Irish citizen')); 
(adoptedirl(X))->write(X) ->write_ln(' qualifies: he/she was adopted by Irish-born parents'); 
(irlparent(X)->write(X) ->write_ln(' qualifies: he/she has an Irish parent')),fail; 
(irlgrandparent(X) ->write(X) ->write_ln(' qualifies: he/she has an Irish grandparent')),fail; 
(permres5(X) ->write(X) ->write_ln(' qualifies: he/she is an Irish permanent resident and has been for at least 5 years')),fail. 

Так что, когда Фиона называется: Фиона квалифицирует: он/она имеет ирландский родитель ложного. возвращается вместо true.

для откровенного его: откровенных квалифицируется: он/она имеет ирландский родитель откровенные квалифицирует: он/она имеет ирландский прародитель ложного.

снова он должен сказать правду, я не уверен, как изменить значение истины, не меняя неудачи, и нарушая обратный путь.

Pastebin из всего кода: http://pastebin.com/tp7Mi5s6

+0

возможно, просто write_ln должно быть написано – CapelliC

ответ

1

метода вы используете, чтобы заставить перечисление всех решений называется «отказ управляемого циклом».

Предикаты с множеством решений, такие как setof/3, могут быть лучше подходят для того, что вам нужно.

Во-первых, я бы заменить qualify/1 с person_qualified_reason/3:

person_qualified_reason(P,Decision,Reason) :- 
    citizen(P), 
    !, 
    Decision = no, 
    Reason = 'already an irish born citizen'. 
person_qualified_reason(P,Decision,Reason) :- 
    natcitizen(P), 
    !, 
    Decision = no, 
    Reason = 'already a naturalized Irish citizen'. 
person_qualified_reason(P,yes,'married to an Irish citizen') :- 
    marriedirl(P). 
person_qualified_reason(P,yes,'adopted by Irish-born parents') :- 
    adoptedirl(P). 
person_qualified_reason(P,yes,'has an Irish parent') :- 
    irlparent(P). 
person_qualified_reason(P,yes,'has an Irish grandparent') :- 
    irlgrandparent(P). 
person_qualified_reason(P,yes,'has been Irish permanent resident for 5+ years') :- 
    permres5(P). 

Пример запроса:

?- person_qualified_reason(frank,D,Reason). 
D = yes, Reason = 'has an Irish parent' ; 
D = yes, Reason = 'has an Irish parent' ;   % redundant answer 
D = yes, Reason = 'has an Irish grandparent' ; 
D = yes, Reason = 'has an Irish grandparent' ;  % redundant answer 
false. 

Чтобы собрать все причины, мы можем использовать встроенный setof/3:

?- setof(Decision-Reason,person_qualified_reason(frank,Decision,Reason),All). 
All = [yes-'has an Irish grandparent', yes-'has an Irish parent']. 

knownPerson/1 действует для всех лиц Известно, в базе данных:

knownPerson(X) :- adopted(X,_,_). 
knownPerson(X) :- adopted(_,X,_). 
knownPerson(X) :- adopted(_,_,X). 
knownPerson(X) :- naturalized(X,_). 
knownPerson(X) :- permres(X,_,_). 
knownPerson(X) :- child(X,_,_). 
knownPerson(X) :- child(_,X,_). 
knownPerson(X) :- child(_,_,X). 
knownPerson(X) :- married(X,_,_). 
knownPerson(X) :- married(_,X,_). 
knownPerson(X) :- born(X,_,_). 

Чтобы избавиться от избыточных ответов knownPerson/1 определит вспомогательный предикат:

person(X) :- setof(t,knownPerson(X),_). 

В конце концов, давайте посмотрим, кто квалифицирован, кто нет, и по каким причинам. Я взял данные, которые вы поставили в ссылке pastebin:

?- person(P), 
    setof(Q-Reason,person_qualified_reason(P,Q,Reason),Verdict). 
P = aisling, Verdict = [yes-'has an Irish grandparent']   ; 
P = andy, Verdict = [no-'already a naturalized Irish citizen'] ; 
P = anna, Verdict = [yes-'has an Irish grandparent']   ; 
P = brendan, Verdict = [no-'already an irish born citizen']  ; 
P = bridgen, Verdict = [no-'already an irish born citizen']  ; 
P = bridget, Verdict = [yes-'has an Irish parent'] ... 
Смежные вопросы