문제

프롤로그에서 가계도를 시뮬레이션해야합니다. 그리고 나는 기교적 곤경에 문제가있다.사리:

parent(x,y).
male(x).
female(y).
age(x, number).

규칙 :

blood_relation 나에게 두통을주고있다. 이것이 제가 한 일입니다.

blood_relation(X,Y):-ancestor(X,Y).
blood_relation(X,Y):-uncle(X,Y);brother(X,Y);sister(X,Y);(mother(Z,Y),sister(X,Z));(father(Z,Y),sister(X,Z));(father(Z,Y),brother(X,Z)).
blood_relation(X,Y):-uncle(X,Z),blood_relation(Z,Y).

그리고 나는 만족스러운 결과 (이중 인쇄물이 있습니다 - 이것을 고칠 수 있습니까)라고 생각합니다. 문제는이 관계가 대칭이되기를 원한다는 것입니다. 지금은 아닙니다.

blood_relation(johns_father, joh):yes 
blood_relation(john,johns_father): no

그래서 .. 이것을 고치는 방법이 있습니다. 그리고 나는 쿼리가 필요하다 : blood_relation에 있지 않은 모든 쌍 ..

업데이트:

첫 번째 진술은 어떤 종류의 관계가 만족해야합니까? Blood_relation (x, y) :-Blood_relation (x, y).

죄송합니다. 사본/페이스트입니다

blood_relation(X,Y):-ancestor(X,Y).

이제 위에 고정되었습니다.

다른 규칙은 다음과 같습니다.

father(X,Y):-parent(X,Y),male(X).  
mother(X,Y):-parent(X,Y),female(X).  
brother(X,Y):-parent(Z,X),parent(Z,Y),male(X).  
sister(X,Y):-parent(Z,X),parent(Z,Y),female(X).  
grandFather(X,Y):-parent(Z,Y),parent(X,Z),male(X).  
grandMother(X,Y):-parent(Z,Y),parent(X,Z),female(X).  
uncle(X,Y):-mother(Z,Y),brother(X,Z).  
ancestor(X,Y):-ancestor(X,Y).  
ancestor(X,Y):-parent(X,Z),ancestor(Z,Y).

어머니의 형제는 삼촌 정의에 있습니다. 그것은 이상합니다. 구현 해야하는 규칙이 있으며 그 외에 규칙을 구현할 수있는 방법을 모르겠습니다. 난 그냥 혼란 스러워요.

어떻게 만드는 방법 blood_relation 대칭? 그리고 not_blood_relation 새로운 규칙입니다. 그리고 쿼리가 필요합니다. 이것은 정말로 나에게 두통을주고 있습니다. 어쩌면 관계는 쓰레기처럼 쓰여졌 기 때문일 수 있습니다.

그리고 더 이상 사실이 없습니다. 그게 다야. 모든 규칙과 모든 사실.

질문.. not(blood_relation(X,Y)) 작동하지 않으며 왜 그런지 모르겠습니다. 예를 들어 쿼리 :

age(X,Y), Y>18,  
not(parent(X,Z)),write(X),nl,fail.

잘 작동합니다

도움이 되었습니까?

해결책

조금은 숙제처럼 보이지만 ...

Prolog의 초보자가 생각하지 않는 한 가지 트릭은 목록 패턴 매칭입니다. [a1, [a2], [b2, [[e3], [f3]], [c2]]와 같은 나무를 생각하십시오. <tree> = [루트, [<tree1>,<tree2>,...]]:

%Y is immediate child of X?
child(X,Y,[X|S]) :- member([Y|_],S).

%pick one tree in S and check
child(X,Y,[X|S]) :- member([Z|SS],S),child(Z,Y,[Z|SS]).

%X and Y end up with same root?
sib(X,Y,[R|T]) :- child(R,X,[R|T]), child(R,Y,[R|T]).

나는 당신이 쌍으로 뿌리를 사용하고, 성별을 추가하고, 나무 구성원의 특정 관계에 이름을 부여하는 것처럼 이것을 개선 할 수 있다고 생각합니다 ...

다른 팁

특정 식 미리 대칭을 만드는 순진한 솔루션은 괜찮은 것과 그리 멀지 않습니다. 일반성을 위해 사람들이 삼촌 등을 넘어 가지 않도록 우정 관계를 살펴 보겠습니다.

다음은 우정 관계를 자세히 설명하는 몇 가지 사실입니다 (예를 들어, 숫자는 사용자 ID이며 논쟁의 특정 순서는 우정을 시작한 사람으로부터 나왔습니다).

friends(1,2).
friends(5,2).
friends(7,4).

당신은 처음에 ""와 같은 규칙을 생각할 것입니다.friends(A,B) :- friends(B,A)."바로 문제를 해결할 수는 있지만, 이것은 Prolog에게 논쟁을 한 번 더 교환하면 단지 작동 할 수 있다고 Prololl에게 무한 재귀로 이어집니다."@</2"이것은"표준의 표준 순서 "에서 한 용어 (변수조차도)가 다른 용어보다 먼저 오는지 여부를 알려줍니다. 기술적 의미는 여기서 그다지 중요하지는 않지만 우리가 관심을 갖는 것은 두 가지 다른 용어에 대해서만 사실이라는 것입니다. 하나의 순서를 위해. 우리는 이것을 사용하여 무한 재귀를 깨뜨릴 수 있습니다!

이 단일 규칙은 제작을 돌볼 것입니다. "friend/2"대칭.

friends(A,B) :- A @< B, friends(B,A).

이것이 깔끔한만큼, 당신이 접근 방식이 있습니다. ~해야 한다 대규모 프로젝트를 시작하십시오. 내 사실 목록에서 Args의 순서는 실제 의미 (우정을 시작한 사람)가 있다는 것을 상기하십시오. 최종 규칙을 추가하면이 정보에 대한 향후 액세스가 파괴되었으며, 코드를 읽는 다른 사람들의 경우 하드 코딩 된 데이터 블록에 쉽게 무시할 수있는 한 줄의 코드로 대칭 속성을 숨 깁니다.

산업 강도 솔루션을 Condsider :

friended(1,2).
friended(5,2).
friended(7,4).

friends(A,B) :- friended(A,B).
friends(A,B) :- friended(B,A).

부러 지지만 모호한 곤경을 사용하지 않고 깨끗하게 읽히고 원래 정보를 유지합니다 (실제 응용 프로그램에서 언젠가 다시 원할 수도 있음).

--

쌍을 찾는 것에 관해서는 ~하지 않다 특정 속성이 있으시면 실제 개인을 찾기 위해 부정을 사용할 때 규칙에 문맥을 제공하기 위해 항상 술어를 포함시켜야합니다.

potential_enemies(A,B) :- user(A), user(B), \+ friends(A,B).

첫 번째 진술은 어떤 종류의 관계가 만족해야합니까?

blood_relation(X,Y):-blood_relation(X,Y).

그것은 당신이 아직 "알지 못하고"당신에게 재귀 두통을 일으킬 것이라고 말하는 것이 아닙니다. '아니오'답변에 관해서는, 이미 당신이 얻을 쿼리에서 모든 답변을 얻은 것처럼 보이며, 통역사는 더 이상 없다고 말합니다.

당신은 정말로 더 많은 사실과 삼촌/2의 정의를 게시해야하며, 당신이 어머니의 형제, 언니와 일치하지 않는 이유가 있습니까? 당신은 다음과 같은 다른 문제가 많이 있습니다 :-).

혈액 관계가 아닌 모든 것에 대해 다음과 같이 시도하십시오.

not_blood_relation(X, Y) :- blood_relation(X, Y), !, fail.
not_blood_relation(X, Y).

그리고 왜 그것이 작동하는지 스스로에게 물어보십시오!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top