인공지능언어 PROLOG

 

전문가 시스템 원리와 개발 : 이재규, 최형림, 김현수, 서민수, 주석진, 지원철 공저, 법영사, 1996, Page 238~249

 

1. 서론

2. 사실 (Facts)

3. 물음 (Questions)

4. 변수 (Variables)

5. 논리적 (Conjunctions)

6. 규칙(Rules)

7. Cut

 

 

1. 서론

PROLOG는 1973년 마르세이유 대학 인공지능 연구실에서 A. Colmerauer와 P. Roussel에 의해 개발된 논리지향적 언어이다. 특히 술어논리(Predicate Logic)에 기반을 두고 있다. PROLOG는 LISP 보다는 규모가 작기 때문에 PC를 비롯한 여러 종류의 컴퓨터에서 실행이 가능하다. PROLOG는 전문가시스템의 연구에는 기여를 해왔으나 대형전문가시스템 개발에는 적합하지 못하다. 그러나 병렬탐색에 적합하게 설계되어 있기 때문에 병렬처리가 주요 요소가 될 미래의 컴퓨터에 적합한 언어로 여겨지고 있다. 미래의 언어에는 이러한 기능들이 첨가되어 발전하게 될 것이다. PROLOG은 유럽과 일본에서 많이 사용되고 있으며, 이것의 특성 중 일부는 LISP에서도 구현되고 있다. 다음의 <표 1>에는 현재 상용화되어 있는 PROLOG 컴파일러에 대한 목록이 열거되어 있다.

 


<표 1> PROLOG 컴파일러

PROLOG 컴파일러

환경(H/W, OS, 기타)

개 발 회 사

AAIS Full Control

Macintosh Plus

Advanced AI Systems

Arity

DOS

Arity Co.

ALS

DOS, UNIX

Applied Logic Systems

BIM

SPARC, 8M RAM

BIM

Cogent

DOS

Amziod

Delphia

SPARC

Delphia

IF

DOS, UNIX, Windows

American Interface Computer

LPA

DOS, Windows, Macintosh

Logic Programming Associates

n-parallel

DOS

Computer Systems Architects

PDC

DOS, OS/2, Windows

Prolog Development Center

Quintus

DOS, UNIX

Quintus Co.

PROLOG는 대상(Object)과 대상간의 관계(Relationship)를 포함하고 있는 문제를 해결하는데 사용되는 언어이다. 예를 들어, "John은 책을 가지고 있다."는 문장은 John이라는 대상과 책이라는 또 다른 대상간의 소유관계를 선언하고 있다(관계에서는 대상간의 순서가 중요).
   PROLOG 프로그래밍은 다음과 같은 사항들로 되어 있다.
   1) 대상과 그들간의 관계에 대한 사실(Facts) 선언
   2) 대상과 그들간의 관계에 대한 규칙(Rules)의 정의
   3) 대상과 그들간의 관계에 대한 물음(Questions)

   따라서 PROLOG 시스템은 사실들과 규칙들로 이루어져 있고, 이것들로 물음에 대한 대답을 한다.

2. 사실 (Facts)

   "John은 Mary를 좋아한다"는 사실은 PROLOG에서는 다음과 같이 표현될 수 있다.

        likes(john, mary).

   여기서 john과 mary는 대상이고, likes는 관계이다.
   사실들로 대상간의 관계를 정의할 때에는 괄호 안에 열거될 대상들의 순서에 주의하여야 한다. 위의 예에서 likes(mary, john)과 같이 john과 mary의 순서를 바꾸면 이는 "Mary는 John을 좋아한다"로 해석된다.
   PROLOG에서는 다음과 같은 사항에 주의해야 한다.
   1) 대상과 관계의 명칭은 반드시 알파벳 소문자로 시작해야 한다.
   2) 관계를 쓴 후에 대상들이 콤머로 구분해서 열거되며, 대상들은 소괄호 안에 열거된다.
   3) 사실 표현의 끝에는 마침표를 찍는다.   

   아래의 사실의 예들과 그것들의 해석을 보기로 하자.

     

  (예)

 

 

    valuable(gold).                 
    female(jane).                   
    owns(john, gold).            
    father(john, mary).          
    gives(john, book, mary).

금은 귀중하다.
Jane은 여자이다.
John이 금을 가지고 있다.
John은 Mary의 아버지이다.
John이 Mary에게 책을 준다.


   위의 예에서 소괄호 안에 열거된 대상들을 인수(Arguments)라 하고, 괄호 앞의 관계는 술어(Predicate)라 한다. valuabel은 한 개, likes는 두 개의 인수를 가지고 있는 술어이다.
   관계(Relationship)는 임의의 개수의 인수들을 가질 수 있다. 예를 들어 play라는 술어를 정의하려면, 두 사람 이상의 선수와 그들이 하는 게임의 명칭이 필요하다. 따라서 세 개 이상의 인수가 필요하다. 예를 들어,

        play(john, mary, football).
        play(jane, jim, badminton).

   등과 같이 표현될 수 있다.

3. 물음 (Questions)

   어떤 사실이 있다면 그것에 대한 물음을 할 수 있다. PROLOG에서는 물음은 사실(Facts)과 비슷하게 표현하지만, 그 앞에 특수한 심볼을 붙여야 한다. 이 심볼은 물음표와 하이픈으로 구성된다.
   PROLOG로 표현된 다음과 같은 질문을 생각하여 보자.

        ?- owns(mary, book).

   이 물음에서 mary를 "Mary"라 불리우는 사람으로 해석을 하고, book을 어떤 특정의 책을 의미한다고 하면, 이 물음은 "Mary가 그 책을 가지고 있는가?"라는 물임이 된다.
   이 물음에 대하여 PROLOG는 어떻게 답하는가 보기로 하자.
   1) 이러한 물음에 대하여 PROLOG는 사실들을 모아 놓은 데이터베이스에서 물음의 사실부분과 일치하는 사실들을 찾게 된다.
   2) 만일 일치되는 사실을 찾게 되면 PROLOG는 yes라 답하며, 못 찾는 경우에는 no라 답한다. no라는 것은 일치하는 사실이 없음을 의미한다.

   다음과 같은 데이터베이스를 생각해 보자.

        likes(joe, fish).
        likes(joe, mary).
        likes(mary, book).
        likes(john, book).

   이것들에 대하여

        ?- likes(joe, money).
        no
        ?- likes(mary, joe).
        no
        ?- likes(mary, book).
        yes
        ?- king(john, france).
        no

   여기서 no라는 것은 물음에 부합하는 것이 아무 것도 없다는 뜻이며, false를 의미하는 것은 아니다. 다음과 같은 그리스 철학자에 대한 데이터베이스를 생각해 보자.

        human(socrates).
        human(aristotle).
        athenian(socrates).

   이것에 대하여 다음과 같은 물음을 한다면,

        ?- athenian(socrates).
        yes
        ?- athenian(aristotle).
        no
        ?- greek(socrates).
        no

   역사적으로 볼 때, 실제로 아리스토텔레스가 아테네에서 살았었으나 위의 데이터베이스로부터는 그 사실을 증명할 수 없다. 더구나, 데이터베이스에는 소크라테스가 아테네 사람이라는 사실이 있으나, 이것이 그가 그리스인이라는 것을 증명해 주지는 못한다. 따라서 no라는 답변은 "증명할 수 없다"는 의미로 해석할 수 있다.

4. 변수 (Variables)

   "John은 Mary를 좋아합니까?"라고 묻는 대신에 "John은 X를 좋아합니까?"라고 묻는다면 X가 무엇을 의미하는지 알 수가 없다. 이 경우 X를 변수라 부른다. PROLOG에서 변수를 사용하는 경우, 변수는 instantiate되거나 not instantiate되거나 한다. instantiate가 되었다는 것은 변수가 뜻하는 대상이 존재한다는 의미이다. 변수는 알파벳 대문자로 시작함으로써 대상들의 명칭과 구별된다.

   다음과 같은 사실들로 구성된 데이터베이스가 있다고 하자.

        likes(john, flowers).
        likes(john, mary).
        likes(paul, mary).

   이것들에 대하여 다음과 같은 물음이 있다고 하자.

        ?- likes(john, X).

   이 물음은 "John이 좋아하는 것이 무엇입니까?"라는 의미이며, 이에 대하여 PROLOG는 X=flowers라고 답한다. 이 과정을 보면,
   1) PROLOG는 데이터베이스의 처음부터 찾기 시작하여 likes(john, flowers)를 찾게 된다. X는 flower를 의미하게 된다.
   2) 또한 데이터베이스에는 일치하는 사실이 발견된 곳을 표시한다. 만일 Return키를 치면 PROLOG는 탐색을 중단한다. 이때 ";" 키와 Return키를 치면 바로 전에 표시해 놓은 곳부터 탐색을 다시 시작한다.
   3) 다음에 일치하는 사실은 likes(john, mary)이다. 변수 X는 mary로 instantiate며 likes(john, mary)에 표시를 남기고 X=mary라고 답한다.

   다음 같은 질문에 대해 PROLOG는 다음과 같이 답한다.

        ?- likes(X, mary).      질문 "Mary를 좋아하는 대상이 무엇인가?"
        X=john;                     첫번째 답. ";"를 치면
        X=paul;                     두번째 답. 다시 ";"를 치면
        no                            더 이상의 답이 없음

5. 논리적 (Conjunctions)

   다음과 같은 물음이 있다고 하자.

        "John과 Mary는 서로 좋아하는가?"

   그리고 다음과 같은 데이터베이스가 있다고 하자.

        likes(mary, food).
        likes(mary, wine).
        likes(john, wine).
        likes(john, mary).

   위의 질문은 "John은 Mary를 좋아합니까? 그리고 Mary는 John을 좋아합니까?"와 같은 의미이므로 두 개의 목표(Goal)를 동시에 만족시켜야 한다. 이는 목표 사이에 콤머를 사용하여 다음과 같이 표현된다.

        ?- likes(john, mary), likes(mary, john).

   데이터베이스에는 John은 Mary를 좋아한다는 사실이 있으므로 첫번째 목표는 참이다. 그러나 Mary가 John을 좋아한다는 사실은 없기 때문에 두번째 목표는 거짓이다. 우리는 두 사람이 서로 좋아하는가를 알고자 하는 것이므로 PROLOG는 이 물음에 대하여 no로 답한다.
   다음과 같은 물음이 있다고 하자.

        "John과 Mary가 모두 좋아하는 것이 무엇입니까?"

   이 물음도 다음 두 개의 목표들로 들어 있다. 첫째, Mary가 좋아하는 것들을 찾는다. 둘째, 그것들 중에서 John이 좋아하는 것을 찾는다. 이것은 PROLOG로 다음과 같이 표현된다.

        ?- likes(mary, X), likes(john, X).

   PROLOG는 다음과 같은 절차로 답을 찾아낸다.

☞ 되돌림추적이란 PROLOG가 conjunction에 있는 목표를 만족시키려 할 때, 만일 만족이 안되면 바로 전에 만족한 목표와 관련된 사실이 표시(마크)되어 있는 곳으로 다시 되돌아와 목표를 다시 만족시키고자 하는 것을 의미한다.

 

6. 규칙(Rules)

   다음과 같은 사실이 있다고 하자.

        "John은 모든 사람을 좋아한다."

   이것은 데이터베이스에 다음과 같이 표현될 수 있다.

        likes(john, alfred).
        likes(john, betrand).
        likes(john, charles).
        likes(john, david).
        ...

   그러나 이렇게 하나하나 열거하는 것보다는 John이 좋아하는 것을 규칙의 형태로 표현한다면 훨씬 효율적일 것이다. 규칙은 어떤 사실이 다른 사실들의 집합에 의존적일 경우에 사용된다. 이때 규칙을 표현하는데 만일(if)이라는 단어가 사용된다.

   (예)
        나는 만일 비가 오면 우산을 사용한다.

    규칙은 또한 어떤 것을 정의하는데 사용된다.

   (에)
        만일 X가 동물이고 날개가 있다면 X는 새이다.                     (1)
        만일 X와 Y가 여성이고 X와 Y의 부모가 같다면, X와 Y는 자매간이다.(2)

   규칙은 대상과 그들간의 관계에 대한 일반적인 표현이다. 규칙은 head와 body로 구성되며, ":-"로 연결된다. 아래의 예는 규칙으로 다음과 같이 표현된다.

        "John은 포도주를 좋아하는 사람을 좋아한다."

   또는 변수를 사용하여

        "만일 X가 포도주를 좋아한다면 John은 X를 좋아한다."
        likes(john, X) :- likes(X, wine).

   규칙의 head부분은 likes(john, X)이며 규칙이 정의하고 싶은 사실을 기술한다.
   규칙의 body부분은 likes(X, wine)이며 head가 참이기 위해서 만족시켜야할 목표들을 기술한다.
   위의 예 (2)를 다음과 같이 정리하고 이를 PROLOG규칙으로 표현하면 다음과 같다.

        X is female,
        Y is female,
        X has mother M and father F, and
        Y has the same mother and father as X does.
        =>
        sister_of(X, Y) :- female(X),
                           female(Y),
                           parents(X, M, F),
                           parents(Y, M, F).

7. Cut

   Cut은 만족된 목표(Goal)를 따라 Backtracking을 할 때, 이미 선택되었던 것은 다시 고려의 대상이 되지 못하도록 하고 있다. 이렇게 함으로써 프로그램의 수행속도를 높이고 효율적인 메모리의 사용이 가능해진다. Cut은 목표가 있는 규칙에 '!'를 사용하여 나타낸다. Backtracking시 '!'가 있는 목표가 한 번 만족되면 이 목표는 다시 만족되어지지 않는다.
   Cut이 어떻게 작동하는지를 예를 통하여 보기로 하자. 다음은 도서관의 시설들을 어떤 사람들에게 사용할 수 있도록 해줄 것인가라는 문제이다. 열람실과 같은 기본적인 시설은 모든 사람들에게 개방되어야 한다. 반면에 대출은 선택적으로 이루어져야 한다. 다음의 예는 책을 빌려간 사람이 기일이 지나도 도서반납을 하지 않는 경우, 여러 부속시설들을 이용하지 못하도록 하는 프로그램의 일부이다.

        facility(Pers, Fac) :- book_overdue(Pers, Book),!,basic_facility(Fac).
        facility(Pers, Fac) :- general_facility(Fac).
        basic_facility(reference).
        basic_facility(enquiries).
        additional_facility(borrowing).
        additional_facility(inter_library_loan).
        general_facility(X) :- basic_facility(X).
        general_facility(X) :- additional_facility(X).
        book_overdue('C. Watzer', book10089).
        book_overdue('A. Jones', book29907).
        ...
        ...
        client('C. Watzer').
        client('W. Netesk').

   이제 어떤 사람들에게 어떤 시설을 이요할 수 있도록 해줄 것인가 보기로 하자.

        ?- client(X), facility(X, Y).

   라는 질문에 대하여 PROLOG는 첫번째 사람 'A. Jones'를 찾아낸다. 이 사람이 책 여러 권의 반납을 지체했다고 하자. 어떤 시설을 이용할 수 있게 할 것인가를 알기 위해 PROLOG는 Facility에 대한 첫번째 문을 찾는다. 여기에는 그가 지체한 책이 있는가에 대한 목표가 있다. 이어 A. Jones가 지체한 책이 있다는 사실을 찾아낸다. 다음의 목표는 Cut이다. 이 목표가 만족되고 Facility문이 선택되었으므로 모든 결정을 여기서 내린다. 이 과정을 그림으로 나타내 보면,

   

   Cut을 만나면 지금까지의 흐름이 끊기고, Facility 목표와 Cut 목표 사이의 모든 것을 피하도록 흐름의 경로를 바꾼다. 즉, book_overdue('A. Jones', Book)의 또 다른 해를 찾지 않는다. 또한 두번째 Facility문도 고려하지 않는다. 이 예에서 "Cut"의 영향은 다음과 같이 기술될 수 있다 :
   만일 반납일이 지난 책을 가진 사용자가 있으면, 그 사람은 도서고나의 기본시설만을 사용할 수 있도록 한다. 그 사람이 지체한 모든 책을 찾을 필요가 없으며, 시설에 관한 다른 규칙들도 고려하지 않는다.
   위의 예에서 Cut 은 그것이 있는 곳에서부터 소급한 Facility 목표 내에서 모든 결론을 내도록 한다. 이를 Cut Goal의 Parent Goal이라 한다. 이를 만족시키는 또 다른 모든 해들은 무시되며 Parent Goal과 Cut Goal 사이의 어떤 Goal도 만족시키려는 시도를 하지 않는다.