[ 一日30分 인생승리의 학습법 ] prolog 문법 : Prolog Syntax
2022.11.21 23:29
[ 一日30分 인생승리의 학습법 ] prolog 문법 : Prolog Syntax
Prolog Syntax
Visual Prolog 에서 문법을 설명한 예제이다. Visual Prolog Tutorial 의 일부이다.
Compound goals (복합 목표) : conjunctions 와 disjunctions (and, or)
Multiple arity ( 여러개의 인수를 가질 때 )
Relentless search for solution (무차별한 탐색)
Cut 의 사용법 : rule에서 이전의 subgoal 로 backtrack을 방지
Cut 의 사용법 : 다음 clause(또는 rule) 로의 backtrack을 방지
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 하게 된다 */
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
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.