2017-03-06 4 views
0

나는 그가 아버지 인 경우 그가 다른 남성이라고 말하고 싶다 if_then_else와 성별 여성프롤로그,

father(pedro-i,beatriz(1347)). 
father(pedro-i,joão(1349)). 
father(pedro-i,dinis(1354)). 
father(pedro-i,joão_grão_mestre_da_ordem_de_avis). 
mother(constança(1320),luis). 
mother(constança(1320),maria(1342)). 


% I want to say that if is the father then is male else is a female 

IF_then_else(X,Y,Z) :- father(X,Y),male. 
IF_then_else(X,Y,Z) :- female. 

답변

2

첫 번째 발언이다 소문자는 대문자가 아니며 대문자는 변수에 사용됩니다.

프롤로그 의 조건부가 값을 반환하지 않는다는 점을 놓친 것처럼 보입니다. 그들은 단지 을 성공하거나 이 실패했을 때을 실패 할 수 있습니다 (그런 의미에서 부울을 "반환"합니다). (부울이 아닌) 출력을 제공하는 방법은 통일을 사용하는 것입니다.

if_then_else(X,Y,male) :- father(X,Y). 
if_then_else(X,Y,female).

을하지만 지금은 또 다른 문제가 :

은 여기처럼 머리에 문자를 넣어하여이 작업을 수행 할 수 있습니다 프롤로그 을 백 트럭. 그래서 첫 번째 절이 성공한 경우에도 두 번째 절이 시도됩니다. 따라서 pedro-i은 모두 malefemale이됩니다. guard을 두 번째 절에 넣으면 Prolog가 father(X,Y) 관계가 있음을 증명할 수 없으면 절이 성공 함을 알리는 것이므로이 문제를 해결할 수 있습니다. 뭔가 같은 :

if_then_else(X,Y,male) :- father(X,Y). 
if_then_else(X,Y,female):- \+ father(X,Y).

그러나 이것은 계산 비용이 문제가 발생할 수 있습니다 :이 father(X,Y). 관계가 있음을 증명하는 데 시간이 오래 걸린다 가능하며, 그러한 관계가 존재하지 않는 경우, 실패하는 것은 그렇게 증명 Prolog가 모든 지점을 검사해야하므로 더 많은 시간이 소요됩니다. 그렇게하면 무한 루프가 발생할 수도 있습니다. 이 경우 (!)을 사용할 수 있습니다. 상처가 발생하면 Prolog는 술어의 다음 절에서 결과를 찾지 않습니다. 그래서 당신은 쓸 수 있습니다 :

if_then_else(X,Y,male) :- father(X,Y), !. 
if_then_else(X,Y,female).

는 다른 방법이 프롤로그의 if-then-else structure를 사용하여 사용할 수 있습니다 명시 적으로 통일 :

if_then_else(X,Y,Z) :- 
    ( father(X,Y) -> Z = male ; Z = female ).