[ 一日30分 인생승리의 학습법 ] prolog 문법 :  Prolog  Syntax

  Prolog  Syntax

 

Visual Prolog 에서 문법을 설명한 예제이다. Visual Prolog Tutorial 의 일부이다.

Prolog 에서의 질의 (query)

자연어를 prolog program으로

변수가 값을 얻는 방법

Anonymous Variables (무명 변수)

Compound goals (복합 목표) : conjunctions 와 disjunctions (and, or)

Prolog 의 기본 program section

Type error

Goal section

Standard domain 만의 사용

Multiple arity ( 여러개의 인수를 가질 때 )

Unification

Backtracking

Relentless search for solution (무차별한 탐색)

Backtracking 의 detail

Backtracking 의 동작 예

Fail predicate의 사용법

Cut 의 사용법 : rule에서 이전의 subgoal 로 backtrack을 방지

Cut 의 사용법 : 다음 clause(또는 rule) 로의 backtrack을 방지

Not predicate 의 사용법

Not predicate 의 사용시 주의

Backtracking 에 관한 연습

 

Prolog 에서의 질의 (query)

일단 prolog 에 일련의 fact 만 부여하면  그 fact 와 관련하여 질문을 할수가 있다,이것을 Querying the prolog system 이라 한다.

 

PREDICATES                /* Predicates = Relations */

  nondeterm likes(symbol,symbol)

 

CLAUSES

  likes(ellen,tennis).      /* ellen, tennis 는 객체, likes 는 관계 */

  likes(john,football).    /* john, football 은 인수, likes 는 predicate */

  likes(tom,baseball).    /* "tom 은 baseball을 likes 한다" 라는 fact */

  likes(eric,swimming).  /* 객체와 관계는 소문자, */

  likes(mark,tennis).     /* 모든 fact 와 rule 은 마침표(.) 로 끝난다 */ 

  likes(bill,Activity):- likes(tom, Activity).

    /* tom 이 어떤 Activity를 likes 한다면 bill도 그 Activity를 like한다 

        는 rule 표현, 변수는 대문자 */

GOAL

  likes(bill, baseball).

 

출력

yes

 

자연어를 prolog program으로

 

PREDICATES    /* clauses 섹션에서 사용될 predicate 선언 */

        nondeterm can_buy(symbol, symbol)

        nondeterm person(symbol)

        nondeterm car(symbol)
        likes(symbol, symbol)
        for_sale(symbol)

 

CLAUSES      /* fact (객체와 그들의 관계) 와 rule 로 구성 */

    can_buy(X,Y):-     /* rule 의 결론부 */

        person(X),       /* rule 의 조건부 */

        car(Y),             /* 조건부는 하나 이상의 AND나 OR로 연결된 부목표를 가짐 */

        likes(X,Y),        /* prolog에서 , 는 AND 이고 ; 는 OR 이다 */

        for_sale(Y).

 

  person(kelly).
  person(judy).
  person(ellen).
  person(mark).

  car(lemon).
  car(hot_rod).

  likes(kelly, hot_rod).
  likes(judy, pizza).
  likes(ellen, tennis).
  likes(mark, tennis).

  for_sale(pizza).
  for_sale(lemon).
  for_sale(hot_rod).

 

GOAL       /* prolog 에 대한 질문 (query) */

        can_buy(Who,What).    /* 기억된 fact 와 질문이 일치한 내용이 있는지 검색 */

 

/* prolog에서 goal을 제공하는 방법은  program 에 Goal 섹션을 두는 방법과  program 실행시 필요한 목표를 dialog window에 제공하는 방법이 있다 */

 

출력

Who=kelly, What=hot_rod  

1 solution

 

변수가 값을 얻는 방법

prolog 는 할당연산자( assignment statement ) 가 없다. 이것이 다른 언어와의 중요한 차이다. prolog에서 변수는 fact 나 rule에서의 상수( constant )와 match 됨으로써 값을 얻는다. 변수가 값을 얻기 전까지를 free 라고하고 값을 얻으면 bound 되었다고 한다. query에서 one solution을 얻기위해 필요로 되는 시간까지만 bound 상태로 있고 ,one solution을 찾으면 unbind 되고 back up 되어 다른 solution을 찾는다.즉 변수에 값을 부여하여 정보를 저장할수 없다. 변수는 정보저장 용도가 아니라 pattern matching process 의 일부분으로 사용된다

 

PREDICATES   

        nondeterm likes(symbol,symbol)

CLAUSES
        likes(ellen,reading).
        likes(john,computers).
        likes(john,badminton).
        likes(leonard,badminton).
        likes(eric,swimming).
        likes(eric,reading). 

GOAL
        likes(Person, reading), likes(Person, swimming).

 

/* 처음에 query 의 처음 part에 대해 top down 방향으로 clauses를 탐색 사작-> 변수 Person은 free상태 (free variable, 자유변수) -> 두번째 인수 reading 과 match 되는 fact를 발견 -> Person 은 ellen 으로 bind 되고 (bound variable, 한정변수) 동시에 fact list 상에 pointer를 위치시킴 -> query 의 두번째 part 수행, 즉 likes(ellen, swimming)을 처음부터 찾는다, Person is ellen에 대해 not true -> Person 은 unbind 되고 다시 free, query 의 처음 part에 대해 다른 solution을 찾는다 -> 또다른 fact를 찾기위해 pointer 위치로 다시 돌아간다, 이것을 backtracking 이라 한다 -> Person 은 다시 eric으로 bound 되고 두번째 part에서 likes(eric,swimming) 라는 fact를 발견하여 matching -> query가 만족되어 결과를 리턴 */

 

출력

Person=eric

1 solution

 

Anonymous Variables (무명 변수)

query에서 어떤 정보를 필요로 하지만 어떤 값을 가지든지 상관없다면 Anonymous Varialbles를 사용할 수 있다. Anonymous Varialbles 는 underscore ("_") 로서 표현된다. Anonymous Variables는 어떤 변수 대신에도 사용할 수는 있지만 결코 값을 가질 수는  없다. 어떤 사람들이 parents 인지를 알려고 한다면 그들의 자식이 누구인지를 알 필요는 없다. 이때에 underscore를 사용하여 변수 공간의 값을 무시한다. 즉 대개 사용자가 관심을 갖지 않는 대상의 변수는 underline을 사용하여 변수 대신 사용한다

PREDICATES
        male(symbol)
        female(symbol)
        nondeterm parent(symbol, symbol)

CLAUSES
  male(bill).
  male(joe).

  female(sue).
  female(tammy).

  parent(bill,joe).
  parent(sue,joe).
  parent(joe,tammy).

GOAL
   parent(Parent, _).

출력

Parent=bill

Parent=sue

Parent=joe

3 solutions

 

Compound goals (복합 목표) : conjunctions 와 disjunctions (and, or)

복합 목표  즉 subgoal A and subgoal B (=conjunction, and)을 표현하기위해 comma (,)를 사용하거나 subgoal A or subgoal B (=disjunction, or)을 표현하기위해 semicolon(;)을 사용한다

PREDICATES
        car(symbol,long,integer,symbol,long)
        truck(symbol,long,integer,symbol,long)
        nondeterm vehicle(symbol,long,integer,symbol,long)

CLAUSES
        car(chrysler,130000,3,red,12000).
        car(ford,90000,4,gray,25000).
        car(datsun,8000,1,red,30000).

        truck(ford,80000,6,blue,8000).
        truck(datsun,50000,5,orange,20000).
        truck(toyota,25000,2,black,25000).

        vehicle(Make,Odometer,Age,Color,Price):-
                  car(Make,Odometer,Age,Color,Price);
        truck(Make,Odometer,Age,Color,Price).

GOAL
        car(Make, Odometer, Years_on_road, Body, 25000).

 /* 값이 정확하게 25000 인 차를 찾아낸다. 좀더 자연스럽게 25000 불 이하의 차를 찾아내려면 car(Make, Odometer, Years_on_road, Body, Cost), Cost < 25000.  과 같이 subgoal A and subgoal B 로 표현해야 한다.  ,000 이하의 car 이거나 ,000 이하의 truck은 ? 를 표현하려면car(Make,Odometer,Years_on_road,Body,Cost), Cost<25000 ; truck(Make,Odometer,Years_on_road,Body,Cost), Cost < 20000. 와 같이 subgoal A or subgoal B 로 표현해야 한다.  */

출력  

Make=ford, Odometer=90000, Years_on_road=4, Body=gray

1 solution

 

Prolog 의 기본 program section

DOMAINS은 prolog의 standard domain이 아닌 사용자가 사용하는 domain을 선언한다. domains와 types 는 같은 의미이다. PREDICATES는 predicate를 선언하고 인수의 domains(types)를 선언한다. prolog에서 제공하는 built-in predicate를 선언할 필요는 없다. CLAUSES는 심장부에 해당한다. 즉 goal을 만족시키기 위한 fact와 rule이 위치한다.

DOMAINS
        product,sum = integer

PREDICATES
        add_em_up(sum,sum,sum)
        multiply_em(product,product,product)

CLAUSES
  add_em_up(X,Y,Sum):-
        Sum=X+Y.
  multiply_em(X,Y,Product):-
        Product=X*Y.     /* 
관계연산자 로서 같다는 의미이다 (C 언어의 할당 연산자 = 와 다르다*/

GOAL
        add_em_up(32,54,Sum).

출력

Sum=86

1 solution

 

Type error

standard domain은 symbol, string, integer, real, char등이 있다.

symbol 은  sequence of character 로서 string 과 문법은 같다. 그러나 strings를 포함하고 있는 hashed symbol-table 에 대한 pointer로서 구현된다. symbol, string는 큰 의미로 상호 interchangeable하다. 그러나 저장방식이 다르다. symbol은 주소를 가지는 look-up table을 가지고서 object들을 찾아가므로 매우 빠르게 match가 돤다.하나의 symbol이 program에서 반복하여 나오면 compact하게 저장할수 있다.반면 string는 table이 없어 match 되는지를 보기위해서 문자 하나하나를 다 검사해야 한다.

DOMAINS
        brand,color = symbol
        age = byte    /* 
byte 형은 8-bit unsigned int (0~255) */

        price, mileage = ulong   /* ulong 형은 32-bit unsigned int */

PREDICATES
        nondeterm car(brand,mileage,age,color,price)

CLAUSES
  car(chrysler,130000,3,red,12000).
  car(ford,90000,4,gray,25000).
  car(datsun,8000,1,black,30000).

GOAL
        car(renault, 13, 40000, red, 12000). /* age 의 byte type error */       

        car(ford, 90000, gray, 4, 25000).  /* age, color type error */ 

 

출력

error    

 

Goal section

기본적으로 goal section은 rule의 body와 같다 (여러개의 subgoal이 있을수 있고 여러개의 condition이 있을수 있다는 의미에서) . 일련의 subgoal의 모임이며 두가지 점에서 rule과 다르다. 첫째는 :- 연산자가 필요없고  둘째는 program수행시 자동으로 goal이 수행된다. 수행중 subgoal 이 모두 만족하면 program은 성공적으로 종료하지만 하나의 subgoal이라도 fail하게되면 program은 fail되었다고 말해진다.

nowarnings      % Special compiler directive; ignore for the moment

PREDICATES
        nondeterm run

CLAUSES
  run:-
        write("*************** Hello World Program **********************"),nl,
        write("Hello World (first)"),nl,
        readchar(_).

  run:-
        write("Hello World (second)"),nl,
        readchar(_).
        
GOAL    
        run.    /* This is an internal goal. */

출력

*************** Hello World Program **********************

Hello World (first)

yes

 

Standard domain 만의 사용

DOMAINS 섹션이 필요없다. 왜냐하면 유일한 standard domain 만이 사용되기 때문이다.

PREDICATES
        nondeterm phone_number(symbol,symbol)

CLAUSES
  phone_number("Albert","EZY-3665").
  phone_number("Betty","555-5233").
  phone_number("Carol","909-1010").
  phone_number("Dorothy","438-8400").

  phone_number("Kim","438-8400")

GOAL
        phone_number(Who, "438-8400").

출력

Who=Dorothy

Who=Kim

2 solutions
        

Multiple arity ( 여러개의 인수를 가질 때 )

다른 arity (인수의 갯수가 다른) 를 가지면서 같은 이름을 가진 predicate 는 완전히 다르게 취급되어야 한다.

DOMAINS
        person = symbol

PREDICATES
        nondeterm father(person)              /* 이 person 은 father 이다 */
        nondeterm father(person, person)  /* 한 person 은 다른 person의 father */

CLAUSES
  father(Man):- father(Man,_).
  father(adam,seth).
  father(abraham,isaac).

GOAL
        father(X).

출력

x=adam

x=abraham

2 solutions

 

Unification

DOMAINS
        title,author = symbol
        pages         = unsigned 

PREDICATES
        book(title, pages)
        nondeterm written_by(author, title)
        nondeterm long_novel(title) 

CLAUSES
        written_by(fleming, "DR NO").
        written_by(melville, "MOBY DICK").

        book("MOBY DICK", 250).
        book("DR NO", 310).

        long_novel(Title):-
            written_by(_, Title),   /* 인수 match를 위해 프로그램 top->down 탐색 */

            book(Title, Length),  /* match시 free 변수에 value를 bind */
            Length > 300. 

GOAL
        long_novel(X). 

출력

x = DR NO

1 solution

 

/* goal을 만족시키기 위해 각자의 subgoal을 만족시켜야 하고 또한 각 인수와 match되는 clause를 찾기위해 프로그램의 위에서 아래로 search하게 된다. goal과 match되는 clause를 찾으면 goal과 clause가 identical해지도록 free variable에 값이 bind된다. 이때 goal은 clause에 unify되었다고 말해지고 이러한 matching과정을 unification이라 한다 */

 

Backtracking

/* 현실 문제를 풀때 논리적인 결론에 이르는 path를 찾아야 한다. 결론이 찾는 답을 주지 못할 때 다른 path를 선택하게 된다.prolog는 주어진 goal에 만족하는 모든 답을 찾아야 한다. 이때 goal을 만족시킬 경우는 다른 답을 찾기 위해, 만족시키지 못할 경우는 답을 찾기위해 database를 처음부터 탐색해 나간다. 이를 backtracking이라하는 backing-up-and-trying-again method 이다. goal에 대한 하나의 solution을 찾기 시작하면서 branching spot ( = backtracking point )을 marker로서 표시하고 first subgoal이 fail 하면 그 point로 되돌아가 다른 subgoal을 try 한다 */

 

PREDICATES
        nondeterm likes(symbol,symbol)
        tastes(symbol,symbol)
        nondeterm food(symbol) 

CLAUSES
  likes(bill,X):-     /* What 은 variable X에 
unified , rule 의 head가 matching됨*/
        food(X),     /* rule의 body에서 첫번째 subgoal 호출(call) */
        tastes(X,good).  

 /* tastes(brussels_sprouts,good)를 찾기위해 top으로부터 탐색. call이 fail하고 자동적으로 backtracking 수행된다 */

       tastes(pizza,good).

 /* 첫번째 subgoal 의 만족여부를 위해 top에서부터 search */
       tastes(brussels_sprouts,bad).

       food(brussels_sprouts).

 /* call된 fact 다음에 backtracking point를 둔다, X 는 brussels_sprouts 로 bind */
       food(pizza).

/* 한번 bind된 변수는 backtracking에 의해서만 free 하게 된다. X는 pizza에 bind 되고 tastes(pizza,good) 가 새로이 호출 (call) 된다. 다시 top으로부터 탐색이 되고 match가 이루어져 goal은 성공적으로 리턴된다. likes rule에서 What은 X와 unify되고 X는 값 pizza와 bind 되었기 때문에 What 은 값 pizza 와 새로이 bind 되어 답을 낸다 */

 

GOAL
        likes(bill, What).
        

출력

What = pizza

1 solution

 

/* rule의 head부 match를 위한 search는 program의 top에서부터 시작한다

새로운 call이 있을 때 그에 match되는 것도 top에서부터 search한다

하나의 call이 성공적으로 match 되면 다른 subgoal을 차례로 수행한다

clause에서 한번 bind된 변수는 backtracking에 의해서만 free 하게 된다 */

 

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

Relentless search for solution (무차별한 탐색)

/* prolog는 문제에 대한 하나의 solution만을 찾는 것이 아니고 가능한 모든 solution들을 전부 찾는다. 그것이 backtracking 의 잇점이다.*/

 

DOMAINS
        child = symbol
        age   = integer

 

PREDICATES
        nondeterm player(child, age)

 

CLAUSES
        player(peter,9).
        player(paul,10).
        player(chris,9).
        player(susan,9). 

GOAL                             /* compound goal */
        player(Person1, 9),  
        player(Person2, 9),
        Person1 <> Person2.

/* 나이가 9살이면서 다른 사람인 Person1 과 Person2을 찾아라 */

 

출력

Person1 = peter, Person2 = chris

Person1 = peter, Person2 = susan

Person1 = chris, Person2 = peter

Person1 = chris, Person2 = susan

Person1 = susan, Person2 = peter

Person1 = susan, Person2 = chris

6 solutions

 

Backtracking 의 detail

backtracking 의 4가지 기본원칙

 

1. subgoal은 위에서 아래로 순서대로 만족되어야 한다

2. predicate clause는 프로그램에 나타나는 순서대로 위에서 아래로 test되어야 한다

3. subgoal이 rule의 head(결론) 과 match되면 다음에 rule의 body(전제)가 만족되어야 한다. 그때 rule의 body가 만족되는 subgoal의 새로운 집합을 구성한다. 이것은 goal tree를 만든다

4. goal tree의 extremities (leaves)각자에 대해 matching fact가 발견되면 비로소 goal이 만족되는 것이다

 

DOMAINS
        name,thing = symbol 

PREDICATES
        likes(name, thing)
        reads(name)
        is_inquisitive(name) 

CLAUSES
        likes(john,wine):-!.    /* subgoal likes(X,wine) 와 match, X는 john과 bind*/

        likes(lance,skiing):-!.
        likes(lance,books):-!.
        likes(lance,films):-!.
        likes(Z,books):-  reads(Z), is_inquisitive(Z).

/* likes(X,books)와 match,변수 Z는 X와 match 가능, unify . rule의 body를 만족시켜야...새로운 subgoal집합으로 tree구성*/

        reads(john).              /* 새로운 subgoal tree를 만족시킴 */

        is_inquisitive(john).     /* extremity 각자에 대한 matching fact */

 

GOAL
        likes(X,wine), likes(X,books)  /* 2개의 subgoal로 구성되는 goal tree */

 

출력

X = john

1 solution

 

Backtracking 의 동작 예

PREDICATES
        nondeterm type(symbol, symbol)
        nondeterm is_a(symbol, symbol)
        lives(symbol, symbol)
        nondeterm can_swim(symbol) 

CLAUSES
  type(ungulate,animal). /* type(X,animal) 과 match, X는 ungulate에 bind */
  type(fish,animal).       /* backtracking point, redo : X는 fish에 bind */

  is_a(zebra,ungulate).  /* is_a(Y,X) 와 match, Y는 zebra와 bind */
  is_a(herring,fish).     /* redo : is_a(Y,ungulate) 와 no match (fail),

                                           Y는 herring에 bind*/
  is_a(shark,fish).            /* " */ /* backtracking point, redo : Y는 shark에 bind */

  lives(zebra,on_land).
  lives(frog,on_land).
  lives(frog,in_water).
  lives(shark,in_water).

  can_swim(Y):-              /* head of rule match */
        type(X,animal),       /* call */
        is_a(Y,X),            /* is_a(Y,ungulate)를 call, is_a(Y,fish)를 call */
        lives(Y,in_water).   /* lives(zebre,in_water)를 call , no match (fail),                                       lives(herring,in_water)를 call, no match,

                                      lives(shark,in_water)를 call, match */

 

GOAL
        can_swim(What),
        write("A ",What," can swim\n").

 

출력

A shark can swim

What = shark

1 solution

 

Fail predicate의 사용법

backtracking mechanism은 불필요한 탐색을 하여 비능률을 초래할수 있다. 즉 단 하나의 (unique)답만을 찾는 경우 라든가 반대로 여러개의 답을 찾기위해 추가적인 탐색을 강요하는 경우가 있다. 이를 위해서 backtracking process를 제어할 필요가 있다. 이를 위해서는 2가지 방법을 사용한다.

1. backtracking을 강요 (force)하는 fail predicate.

2. backtracking을 방지 (prevent)하는 cut ( ! ).

 

하나의 call이 실패하면 backtracking하게 되는데 어떤 경우에는 부가적인 답을 찾기위해서 backtracking을 강제할 경우가 있다. fail 문장은 failure를 강제하고 그럼으로써 backtracking을 야기한다. fail 문장의 효과는 2 = 3 과 같은 impossible subgoal 의 효과와 같다. 다음은 fail 문장의 예이다.

 

DOMAINS
        name = symbol 

PREDICATES
        nondeterm father(name, name)
        everybody 

CLAUSES
        father(leonard,katherine).
        father(carl,jason).
        father(carl,marilyn).
        everybody:-     /* father(X,Y) 의 또다른 답을 위해 backtracking */
           father(X,Y),
           write(X," is ",Y,"'s father\n"),
           fail.          /* 결코 만족될수 없는 항상 fail, backtracking 강요*/
  everybody.         /* fail 이 없다면 backtrack할 이유가 없다 */

                          /* fail 은 last call까지 backtrack 한다 */

GOAL
        everybody.   /* father(X, Y) 보다도 
더 명확한 답을 보여준다*/

 

 /* prolog에서 여러개의 답을 낼수 있도록 마지막 call까지 backtrack하게되는데 이러한 call을 non-deterministic call 이라 한다. 단지 하나의 답만을 낼수 있는 call을 deterministic call이라 한다*/

 

출력

leonard is katherine's father     /*fail에 의해서 가능한 모든 답을 낸다*/

carl is jason's father

carl is marilyn's father

yes

 

Cut 의 사용법 : rule에서 이전의 subgoal 로 backtrack을 방지

backtracking을 막기위해서 exclamation mark (!)를 사용하는 것을 cut 이라 한다. cut을 가로질러 backtrack하는 것은 불가능하다. rule의 body에 subgoal을 위치시키는 것과 같은 방식으로 cut을 위치시킨다. cut 으로의 호출은 즉시 성공하고 다음 subgoal이 호출된다. 일단 cut 이 지나가면 cut 이전의 subgoal로 backtrack하는 것은 불가능하다. 또한 cut을 포함한 predicate를 정의하고 있는 다른 predicate로의 backtrack도 불가능하다. cut 의 용도는 크게 2가지이다.        

1. 의미있는 답이 나올 가능성이 전혀 없다는 것을 미리 알고 있을 때 다른 답을 구하는 것은 시간과 memory의 낭비이다. 이 상황에서 cut을 사용하면 프로그램은 더 빨리 실행되고 memory를 덜 사용한다. 이것을 green cut 이라 부른다

2. 프로그램의 logic이 cut을 요구할 때, 즉 추가의 subgoal 의 고려를 방지하기 위해서 사용한다. 이것을 red cut 이라 한다

 

r1 :- a, b, !, c.

위의 문장에서 subgoal a, b 에 대한 답이 구해진후에 c 에 대한 답이 backtrack에 의해 여러개 구해지더라도 call a, b 에 대한 추가적인 해를 구하기 위한 backtrack는 허용되지 않는다. 또한 predicate r1을 정의한 또다른 clause로의 backtrack도 허용되지 않는다.

 

PREDICATES
        buy_car(symbol,symbol)
        nondeterm car(symbol,symbol,integer)
        colors(symbol,symbol) 

CLAUSES

  buy_car(Model,Color):-
      car(Model,Color,Price),  /*first subgoal*/
      colors(Color,sexy),!,    /*cut을 만나는 순간 bind되었던 변수값들 동결*/
      Price > 25000.              /* test succeed*/                                        

  car(maserati,green,25000).
  car(corvette,black,24000).  /* match,Color 는 black로 bind */
  car(corvette,red,26000).      /*backtrack, match, Color는 red로 bind,

                                            Price는 26000*/
  car(porsche,red,24000). 

  colors(red,sexy).         /* sexy 가 메치됨*/
  colors(black,mean).    /* 선택된 차가 sexy color인지 테스트, fail*/
  colors(green,preppy).

 

GOAL
        buy_car(corvette, Y).

 

/* 위에서 Price < 25000 이라면 test 는 fail, 앞쪽의 subgoal 로 backtrack 할수 없어 fjnal subgoal 인 Price 문제의 해결을 위한 방법은 없고  goal 은 failure 로 끝난다 */

 

출력

Y = red

1 solution

 

Cut 의 사용법 : 다음 clause(또는 rule) 로의 backtrack을 방지

r(1) :- !, a, b, c.

r(2) :- !, d.

r(3) :- !, c.

r(_) :- write ("This is a catchall clause.").

cut을 사용하여 predicate r을 deterministic하게 만든다. r(1), r(2), r(3), r(_) 중에서 하나라도 body of rule이 성공하면 cut은 backtracking point를 제거하여 또다른 r clause로의 backtracking 가능성을 없애서 단 하나의 r만 수행되게 한다. 다른 r 의 어떤 condition도 match가 되지 않을 때 마지막의 error message 문장이 수행된다

 

PREDICATES
        friend(symbol,symbol)
        girl(symbol)
        likes(symbol,symbol) 

CLAUSES
  friend(bill,jane):-
        girl(jane),
        likes(bill,jane),!.
  friend(bill,jim):-
        likes(jim,baseball),!.  
  /* cut이 없다면 답은 2개 */
  friend(bill,sue):-
        girl(sue). 

  girl(mary).
  girl(jane).
  girl(sue). 

  likes(jim,baseball).
  likes(bill,sue).

 

GOAL
        friend(bill,Who).

 

출력

Who = jim

1 solution

 

/* non-deterministic clause를 body of rule 에 cut을 삽입함으로써 deterministic clause로 만들수 있다. 위에서 friend predicate는 하나를 리턴하여 오직 하나의 solution만을 가지므로 deterministic 하다.*/

 

Not predicate 의 사용법

not 은 subgoal이 true라고 증명될수 없을 때 성공한다

 

DOMAINS
        name = symbol
        gpa  = real 

PREDICATES
        nondeterm honor_student(name)
        nondeterm student(name, gpa)
        probation(name) 

CLAUSES
        honor_student(Name):-
             student(Name, GPA),
             GPA>=3.5,
             not(probation(Name)). 

        student("Betty Blue", 3.5).
        student("David Smith", 2.0).
        student("John Johnson", 3.7). 

        probation("Betty Blue").
        probation("David Smith").

 

GOAL
        honor_student(X).
        

출력

X = John Johnson

1 solution

/* probation : 보호 관찰중인 상태 */

 

Not predicate 의 사용시 주의

not 은 부적절하게 사용시 error message를 내거나 logic상의 error를 발생시킨다. 다음은 not 의 적절한 사용예이다.

 

PREDICATES
        nondeterm likes_shopping(symbol)
        nondeterm has_credit_card(symbol,symbol)
        bottomed_out(symbol,symbol) 

CLAUSES
  likes_shopping(Who):-
        has_credit_card(Who,Card),
        not(bottomed_out(Who,Card)),
        write(Who," can shop with the ",Card, " credit card.\n"). 

  has_credit_card(chris,visa).
  has_credit_card(chris,diners).
  has_credit_card(joe,shell).
  has_credit_card(sam,mastercard).
  has_credit_card(sam,citibank).

  bottomed_out(chris,diners).
  bottomed_out(sam,mastercard).
  bottomed_out(chris,visa).

 

GOAL
        likes_shopping(Who).

 

출력

joe can shop with the shell credit card.

Who = joe

sam can shop with the citibank credit card.

Who = sam

2 solutions

 

Backtracking 에 관한 연습

 

다음은 backtracking 에 관한 연습이다.

Bert 는 motive(동기)를 가지고 있고 희생자와 같은 stuff (음식 또는 오물)로 smeared_in (더럽혀졌기) 때문에 유죄다.

 

trace
DOMAINS
        name,sex,occupation,object,vice,substance = symbol
        age=integer 

PREDICATES
        nondeterm person(name, age, sex, occupation)
        nondeterm had_affair(name, name)
        killed_with(name, object)
        killed(name)
        nondeterm killer(name)
        motive(vice)
        smeared_in(name, substance)
        owns(name, object)
        nondeterm operates_identically(object, object)
        nondeterm owns_probably(name, object)
        nondeterm suspect(name) 

 

/* * * 살해 사건과 관련된 사실 * * */
CLAUSES
  person(bert,55,m,carpenter).
  person(allan,25,m,football_player).
  person(allan,25,m,butcher).
  person(john,25,m,pickpocket). 

  had_affair(barbara,john).
  had_affair(barbara,bert).
  had_affair(susan,john). 

  killed_with(susan,club).
  killed(susan). 

  motive(money).
  motive(jealousy).
  motive(righteousness). 

  smeared_in(bert, blood).
  smeared_in(susan, blood).
  smeared_in(allan, mud).
  smeared_in(john, chocolate).
  smeared_in(barbara,chocolate). 

  owns(bert,wooden_leg).
  owns(john,pistol).

 

/* * * 배경 지식 * * */

  operates_identically(wooden_leg, club).
  operates_identically(bar, club).
  operates_identically(pair_of_scissors, knife).
  operates_identically(football_boot, club).

 

  owns_probably(X,football_boot):-
        person(X,_,_,football_player).
  owns_probably(X,pair_of_scissors):-
        person(X,_,_,hairdresser).
  owns_probably(X,Object):-
        owns(X,Object).

 

/* * * * * * * * * * * * * * * * * * * * * * *
 * Susan 이 살해될 만한 무기를 가진 사람을 의심 *
 * * * * * * * * * * * * * * * * * * * * * * */

  suspect(X):-
        killed_with(susan,Weapon) ,
        operates_identically(Object,Weapon) ,
        owns_probably(X,Object).

 

/* * * * * * * * * * * * * * * * * * * * * * * * * *
 * Susan  과 관계를 가진 남자를 의심  *
 * * * * * * * * * * * * * * * * * * * * * * * * * */

  suspect(X):-
        motive(jealousy),
        person(X,_,m,_),
        had_affair(susan,X).

 

/* * * * * * * * * * * * * * * * * * * * *
 * Susan을 아는 어떤 사람과 관계를 가진 여성을 의심 *
 * * * * * * * * * * * * * * * * * * * * */

  suspect(X):-
        motive(jealousy),
        person(X,_,f,_),
        had_affair(X,Man),
        had_affair(susan,Man).

 

/* * * * * * * * * * * * * * * * * * * * * * * * * * *
 * 돈을 노린 소매치기를 의심  *
 * * * * * * * * * * * * * * * * * * * * * * * * * * */

  suspect(X):-
        motive(money),
        person(X,_,_,pickpocket).

 

  killer(Killer):-
        person(Killer,_,_,_),
        killed(Killed),
        Killed <> Killer, /* It is not a suicide */
        suspect(Killer),
        smeared_in(Killer,Goo),
        smeared_in(Killed,Goo).

 

GOAL
        killer(X).

 

출력

X = bert

1 solution

 

[출처] http://www.aistudy.co.kr/program/prolog/visual_prolog_example.htm

 

 

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
1115 [ 一日30分 인생승리의 학습법] 2023 네이버 다이어리 굿노트 템플릿으로 심플하게 새해 계획 file 졸리운_곰 2023.01.07 15
1114 [ 一日30分 인생승리의 학습법] 프로그래밍 스킴 Scheme 1 다운로드부터 문법 대부분을 314초만에 알려줄게요 졸리운_곰 2023.01.05 5
1113 [ 一日30分 인생승리의 학습법] ROBOCOPY(로보카피) 사용법 file 졸리운_곰 2023.01.05 10
1112 [ 一日30分 인생승리의 학습법] PHP, VBA and SQL Useful Scripts PHP, VBA 및 SQL 유용한 스크립트 file 졸리운_곰 2023.01.01 7
1111 [ 一日30分 인생승리의 학습법] KoELECTRA로 기계독해(MRC) API 개발 file 졸리운_곰 2023.01.01 7
1110 [ 一日30分 인생승리의 학습법] 일 안 해도 생기는 수입? 그런 ‘패시브 인컴’은 없다 file 졸리운_곰 2023.01.01 6
1109 [ 一日30分 인생승리의 학습법] Qemu를 이용한 가상화 기초 file 졸리운_곰 2022.12.31 5
1108 [ 一日30分 인생승리의 학습법] 파이토치로 딥러닝해야 하는 5가지 이유 졸리운_곰 2022.12.31 6
1107 [ 一日30分 인생승리의 학습법] 왜 ‘한국어’의 자연어처리(NLP)는 유독 어려울까? file 졸리운_곰 2022.12.31 10
1106 [ 一日30分 인생승리의 학습법] MinIO Windows Service 등록 졸리운_곰 2022.12.24 7
1105 [ 一日30分 인생승리의 학습법] Apache 2.2에서 2.4로 마이그레이션 시 발생하는 에러 및 해결책 정리 졸리운_곰 2022.12.18 6
1104 [ 一日30分 인생승리의 학습법] Git 사용 방법 정리(commit, push, pull request, merge 등) 졸리운_곰 2022.12.04 18
1103 [ 一日30分 인생승리의 학습법] [웹 기획] 화면 설계 용어 - 와이어프레임, 스토리보드, 프로토타입의 차이점 file 졸리운_곰 2022.12.03 6
1102 [ 一日30分 인생승리의 학습법] REST API 설계 (네이밍) 졸리운_곰 2022.11.26 24
1101 [ 一日30分 인생승리의 학습법] REST API URI 규칙 졸리운_곰 2022.11.26 12
1100 [ 一日30分 인생승리의 학습법 ] REST API URL 규칙 졸리운_곰 2022.11.26 9
» [ 一日30分 인생승리의 학습법 ] prolog 문법 : Prolog Syntax 졸리운_곰 2022.11.21 3
1098 [ 一日30分 인생승리의 학습법 ] noVNC 작동원리 file 졸리운_곰 2022.11.16 8
1097 [ 一日30分 인생승리의 학습법 ] 프로젝트 만들고 GitHub에 첫 Commit하고 Push하기 file 졸리운_곰 2022.11.15 4
1096 [ 一日30分 인생승리의 학습법 ] 우분투(리눅스) 에서 EBS 라디오 자동녹음 만들기 졸리운_곰 2022.11.11 9
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED