7주 7개 언어 - Prolog(2)

4326 단어 Prolog

1 귀속


먼저 지식 라이브러리를 살펴보겠습니다.
father(zeb,john_boy_sr).

father(john_boy_sr,john_boy_jr).



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

ancestor(X,Y):-father(X,Y),ancestor(Z,Y).

규칙ancestor/2에는 두 개의 자구가 있다.
만약 하나의 규칙이 여러 개의 자구로 구성된다면, 그 중의 한 자구가 진실이라면, 이 규칙은 진실이다.
다음은 테스트를 해보겠습니다.
|?-ancestor(zeb,Who).



Who=john_boy_sr?a



Who=john_boy_jr



no

이것들은 모두 이전에 말한 것이니 군더더기 말할 필요가 없다.특히 강조해야 할 것은 다음과 같다.
모든 귀속된 하위 목표는 창고 공간을 사용하지만, 결국 창고 공간을 소모할 가능성이 높다.성명식 언어는 일반적으로
최종적으로 최적화된 기술로 이 문제를 해결하다.
귀속 하위 목표를 귀속 규칙의 끝에 놓으면 프로로그는 호출 창고를 버려서 이 호출을 최적화하고 메모리를 사용하지 않습니다.이곳의 호출은 마지막 귀속이다. 왜냐하면 귀속 서브 목표 ancestor (Z, Y) 는 귀속 규칙의 마지막 목표이기 때문이다.

2 목록 및 메타그룹


[1,2,3]로 지정할 수 있어요.
목록, (1,2,3)로 지정할 수도 있습니다.
원조.목록
용기가 길어지고, 원조는
고정 용기.

합일

|?-(A,B,C)=(1,2,3).



A=1

B=2

C=3



yes

|?-[2,2,3]=[X,X,Z].



X=2

Z=3



yes
예는 매우 간단하다.목록에는 원조가 갖추지 못한 능력이 있습니다. 즉, 통과할 수 있습니다.
[Head|Tail] 구성 해제 목록입니다.목록을 이 구조와 일치시키면 Head는 목록의 첫 번째 요소를 연결하고, Tail은 나머지 요소를 연결합니다. 이렇게:
|?-[a,b,c]=[Head|Tail].



Head=a

Tail=[b,c]



yes

주의,
[Head|Tail]은 빈 목록과 일치할 수 없지만 단일 요소 목록은 가능합니다.
|?-[]=[Head|Tail].



no

|?-[a]=[Head|Tail].



Head=a

Tail=[]



yes
두 가지 복잡한 예를 다시 보자.
|?-[a,b,c]=[a|Tail].



Tail=[b,c]



yes

|?-[a,b,c]=[a|[Head|Tail]].



Head=b

Tail=[c]



yes

|?-[a,b,c,d,e]=[_,_|[Head|_]].



Head=c



yes

“_”모든 객체와 일치할 수 있는 와일드카드입니다.

3 목록과 수학 연산

count(0,[]).

count(Count,[Head|Tail]):-count(TailCount,Tail),Count is TailCount+1.



sum(0,[]).

sum(Total,[Head|Tail]):-sum(Sum,Tail),Total is Head+Sum.



average(Average,List):-sum(Sum,List),count(Count,List),Average is Sum/Count.
이 규칙들은 매우 간단하다.다음은 그들의 업무 방식을 점차적으로 설명한다.
  • 조회count(What,[1])를 시작합니다. 목록이 비어 있어서 첫 번째 규칙과 일치할 수 없습니다.두 번째 규칙 카운트(Count, [Head|Tail])의 목표를 계속 충족합니다.합일 작업을 진행하면 What는 Count, Head는 1, Tail은 []로 바인딩됩니다
  • 그리고 이후 첫 번째 목표는count(TailCount, [])로 바뀌었습니다. 우리는 이 하위 목표를 증명하려고 합니다.이번에 우리는 제1조 규칙과 합일한다.TailCount는 0으로 바인딩됩니다.이제 첫 번째 규칙이 충족되었으니 두 번째 목표를 처리하겠습니다..
  • 현재 Count에 대한 값은 TailCount+1입니다.우리는 하나의 변수에 합칠 수 있다.TailCount가 0으로 바인딩되므로 Count를 0+1 또는 1로 바인딩합니다

  • 다른 것들은 더 이상 군더더기 없이 유사하다.

    4 두 방향에서 규칙 사용

    다음에 토론하겠습니다.
    append 규칙.List3이 List1+List2이면 규칙 append(List1, List2, List3)가 진짜입니다.
    |?-append([oil],[water],[oil,water]).
    
    
    
    yes
    
    |?-append([oil],[water],[oil,slick]).
    
    
    
    no

    다음은 목록 구조기입니다.
    |?-append([tiny],[bubbles],What).
    
    
    
    What=[tiny,bubbles]
    
    
    
    yes

    다음 코드는 목록 빼기 작업에 사용됩니다.
    |?-append([dessert_topping],Who,[dessert_topping,floor_wax]).
    
    
    
    Who=[floor_wax]
    
    
    
    yes
    다음 코드는 가능한 배열을 계산하는 데 사용됩니다.
    |?-append(One,Two,[apples,oranges,bananas]).
    
    
    
    One=[]
    
    Two=[apples,oranges,bananas]?a
    
    
    
    One=[apples]
    
    Two=[oranges,bananas]
    
    
    
    One=[apples,oranges]
    
    Two=[bananas]
    
    
    
    One=[apples,oranges,bananas]
    
    Two=[]
    
    
    
    no

    다음은 append를 실현하는 데 얼마나 많은 코드가 필요한지 살펴봅시다.Prolog의 append를 다시 실현하지만,concatenate라고 합니다.단계는 다음과 같습니다.
  • 규칙concatenate(List1, List2, List3)를 작성하여 빈 목록을 List1과 연결할 수 있습니다
  • List1의 요소를 List2와 연결할 수 있는 규칙을 추가합니다..
  • List1의 두 요소 또는 세 요소를 List2와 연결할 수 있는 규칙을 추가합니다..
  • 우리가 어떤 것을 범용할 수 있는지 보자..

  • 코드는 다음과 같습니다.
    concatenate([],List,List).
    
    concatenate([Head|[]],List,[Head|List]).
    
    concatenate([Head1|[Head2|[]]],List,[Head1,Head2|List]).
    
    concatenate([Head1|[Head2|[Head3|[]]]],List,[Head1,Head2,Head3|List]).
    
    

    이것은 앞에서 언급한 간단한 규칙의 사용일 뿐입니다. 군더더기 없이 다음은 중첩된 규칙을 사용한 concatenate를 보십시오.
    concatenate([],List,List).
    
    concatenate([Head|Tail1],List,[Head|Tail2]):-concatenate(Tail1,List,Tail2).

    이 코드는 매우 간단하다. 우선,
    첫 번째 목록이 비어 있는지 판단합니다. 만약 비어 있고 두 번째와 세 번째 목록 시스템이 비어 있다면 규칙은 진실입니다. 이것은 빈 목록과List를 연결하면 그 목록을 얻을 수 있음을 나타냅니다.두 번째 자구는 List1과 List3의 Head가 같고, List1의 Tail과 List2를 연결하면 List3의 Tail을 얻을 수 있음을 증명할 수 있으며, List1과 List2를 연결하면 List3를 얻을 수 있음을 나타낸다.
    여러분의 메모 토론을 환영합니다. 함께 진보합시다!

    좋은 웹페이지 즐겨찾기