2012-01-22 2 views

답변

4

위의 단항 관계 person/1 (단 하나의 인수를 나타냄)으로 작업하고 있습니다. 피터, 밥, 아만다가 사람이라는 사실을 정의합니다. 그런 다음 Prolog에 person(X)person(Y)을 통합하도록 요청합니다. 즉, 표현식이 유지되도록 XY의 가장 일반적인 값을 찾습니다. 물론 우리는 그 대답을 위해서 Y = X을 가질 필요가 있습니다.

이와 같은 조건을 적용하려면 이름을 첫 번째 이름이 아닌 다른 이름으로 나타내야합니다. 그렇지 않으면 암시 적으로 동일하게 나타납니다.

아이디를 사용하십시오.

person(1). 
person(2). 
person(3). 

name(1, peter). 
name(2, bob). 
name(3, amanda). 

다음 프롤로그의 논리적 핵심 내

?- name(Y, X), name(Z, X), Y \= Z. 
0

를 조회는 독특하고 중복 규칙 사이의 구분이 안된다; person(peter)은 증명할 수있는 것이거나 아닙니다. Prolog가 물을 수있는 유일한 질문입니다.

하지만 논리 코어 밖에서 스테핑을 수행하면 산술 및 I/O와 같이 수행 할 수있는 작업이 많아지고 런타임시 데이터베이스가 분리됩니다. 마지막으로 하나는 데이터베이스에서 person(bob). 규칙을 지우고 여전히 증명할 수 있는지 확인할 수 있다는 의미이므로 여기서는 특히 편리합니다.

:- dynamic person/1. 
person(peter). 
person(bob). 
person(amanda). 
우리가 규칙을 제거 retract(person(bob))을 사용할 수, 수행이와

assert(person(bob)) 다시 넣어 : 규칙을 수정할 수 있도록

첫째, 우리는 역동적 펑터를 선언해야합니다.

has_duplicates :- person(X), retract(person(X)), person(X). 

그러나 우리는 아마 모든 것을 우리가 그것을 발견하는 방법을 떠나고 싶어, 그래서 우리는을 통해 이동해야합니다 : 당신이 당신의 데이터베이스를 부수고 괜찮다면

지금, 걸리는 모든입니다 몇 농구 :

has_duplicates :- person(X), retract(person(X)), assert(backup(X)), person(X), restore. 
has_duplicates :- restore, fail. 

restore :- backup(X), retract(backup(X)), assert(person(X)), fail. 
restore :- true. 
0

이 작업을 수행하는 가장 쉬운 방법은 목록에있는 중복이있는 경우 이름과 테스트의 목록을 작성하는 것입니다.

findall(Name,person(Name),NameList) 

않습니다.예를 들어, SWI-prolog를 사용하는 경우 복제본을 확인하는 것은

과 같이 간단 할 수 있습니다. 또는 정렬 전후에 목록의 길이를 확인하십시오 (중복을 삭제). 또는 목록을 정렬하고 목록의 인접 요소가 동일한 목록을 검사하여 실행합니다.

관련 문제