Both sides previous revision
Previous revision
Next revision
|
Previous revision
Next revision
Both sides next revision
|
en:dydaktyka:ggp:gdl [2018/01/17 15:06] msl [End] |
en:dydaktyka:ggp:gdl [2019/01/03 22:50] msl |
Let's start with players "nought" and "cross". There is a special fact ''role'' just to do that: | Let's start with players "nought" and "cross". There is a special fact ''role'' just to do that: |
| |
<code prolog> | <code> |
role(nought) | role(nought) |
role(cross) | role(cross) |
</code> | </code> |
| |
Syntax is the same as in the Prolog (or Datalog) language with the only difference, that there is no dot at the end of the sentece. All constants start with a lower-cased letter and variables are upper-cased. | Syntax is the same as in the Prolog (or Datalog) language with the only difference, that there is no dot at the end of the sentence. All constants start with a lower-cased letter and variables are upper-cased. |
| |
==== Fluents ==== | ==== Fluents ==== |
To define the fluents one uses the ''base'' facts: | To define the fluents one uses the ''base'' facts: |
| |
<code prolog> | <code> |
base(cell(M,N,x)) :- index(M) & index(N) | base(cell(M,N,x)) :- index(M) & index(N) |
base(cell(M,N,o)) :- index(M) & index(N) | base(cell(M,N,o)) :- index(M) & index(N) |
Here '':-'' reprenst implication ''<-''. ''&'' is a logical and. In natural language the first line means: "if M and N represent cells' indexes, then there is a fluent for cell with (M, N) coordinates, telling there is a cross in it". If we didn't use rules, we could write all the fluents by hand: | Here '':-'' reprenst implication ''<-''. ''&'' is a logical and. In natural language the first line means: "if M and N represent cells' indexes, then there is a fluent for cell with (M, N) coordinates, telling there is a cross in it". If we didn't use rules, we could write all the fluents by hand: |
| |
<code prolog> | <code> |
base(cell(1,1,x)) base(cell(1,1,o)) base(cell(1,1,b)) | base(cell(1,1,x)) base(cell(1,1,o)) base(cell(1,1,b)) |
base(cell(1,2,x)) base(cell(1,2,o)) base(cell(1,2,b)) | base(cell(1,2,x)) base(cell(1,2,o)) base(cell(1,2,b)) |
In order to define an action we use the ''input'' predicate: | In order to define an action we use the ''input'' predicate: |
| |
<code prolog> | <code> |
input(R, mark(M,N)) :- role(R) & index(M) & index(N) | input(R, mark(M,N)) :- role(R) & index(M) & index(N) |
input(R, noop) :- role(R) | input(R, noop) :- role(R) |
| |
Now we have to define the initial state of the game (draw the empty board). The ''init'' predicate serves this purpose. For the tic-tac-toe every cell should be empty, and the ''nought'' player should play first. | Now we have to define the initial state of the game (draw the empty board). The ''init'' predicate serves this purpose. For the tic-tac-toe every cell should be empty, and the ''nought'' player should play first. |
<code prolog> | |
| <code> |
init(cell(M,N,b)) :- index(M) & index(N) | init(cell(M,N,b)) :- index(M) & index(N) |
init(control(nought)) | init(control(nought)) |
To define the state evolution we use the ''next'' predicate, defining the fluent state in the next turn. The 'does' predicate check what actions were made by the players during the current turn. | To define the state evolution we use the ''next'' predicate, defining the fluent state in the next turn. The 'does' predicate check what actions were made by the players during the current turn. |
| |
<code prolog> | <code> |
next(cell(M,N,x)) :- | next(cell(M,N,x)) :- |
does(cross,mark(M,N)) & | does(cross,mark(M,N)) & |
Every player knows that there are two ways to finish the game: make a line or fill all the available cells. Now we will check if there was a line made by the player. | Every player knows that there are two ways to finish the game: make a line or fill all the available cells. Now we will check if there was a line made by the player. |
| |
<code prolog> | <code> |
line(Z) :- row(M,Z) | line(Z) :- row(M,Z) |
line(Z) :- column(M,Z) | line(Z) :- column(M,Z) |
Now we can define the ending conditions with the ''terminal'' predicate: | Now we can define the ending conditions with the ''terminal'' predicate: |
| |
<code prolog> | <code> |
terminal :- line(x) | terminal :- line(x) |
terminal :- line(o) | terminal :- line(o) |
Bots don't have feelings but we still should give them prize for the good game. And we do this with the ''goal'' predicate: | Bots don't have feelings but we still should give them prize for the good game. And we do this with the ''goal'' predicate: |
| |
<code prolog> | <code> |
goal(cross,100) :- line(x) & ~line(o) | goal(cross,100) :- line(x) & ~line(o) |
goal(cross,50) :- ~line(x) & ~line(o) | goal(cross,50) :- ~line(x) & ~line(o) |
There is no arithmetics in GLD --- numbers are only used to define indexes, prizes, time, etc. | There is no arithmetics in GLD --- numbers are only used to define indexes, prizes, time, etc. |
</WRAP> | </WRAP> |
| |
| |
==== End ==== | ==== End ==== |
Let's take an even simpler game: | Let's take an even simpler game: |
| |
<code prolog> | <code> |
role(white) | role(white) |
role(black) | role(black) |
| |
terminal :- true(p) & true(q) & true(r) | terminal :- true(p) & true(q) & true(r) |
| |
</code> | </code> |
| |
Answer the following questions: | Answer the following questions: |
- how many players are there? <fs xx-small>(correct answer: 2, why?)</fs> | - how many players are there? <fs xx-small> (correct answer: 2, why?)</fs> |
- how many fluents are defined? <fs xx-small>(correct answer: 4, why?)</fs> | - how many fluents are defined? <fs xx-small>(correct answer: 4, why?)</fs> |
- how many actions are there? <fs xx-small>(correct answer: 8, why?)</fs> | - how many actions are there? <fs xx-small>(correct answer: 8, why?)</fs> |
Everything we learned so far is true, but the GDL has an alternative syntax used to store and transfer the games: the Knowledge Interchange Format. It's based on a lisp and uses a prefix notation. Moreover '':-'' operator is replaced with ''<='', ''&'' with ''and'', negation ''~'' with ''not''. The variables start with the ''?''. Below you can see an example of translation between Prolog: | Everything we learned so far is true, but the GDL has an alternative syntax used to store and transfer the games: the Knowledge Interchange Format. It's based on a lisp and uses a prefix notation. Moreover '':-'' operator is replaced with ''<='', ''&'' with ''and'', negation ''~'' with ''not''. The variables start with the ''?''. Below you can see an example of translation between Prolog: |
| |
<code prolog> | <code> |
p(a,Y) | p(a,Y) |
~p(a,Y) | ~p(a,Y) |
and KIF: | and KIF: |
| |
<code lisp> | <code scheme> |
(p a ?y) | (p a ?y) |
(not (p a ?y)) | (not (p a ?y)) |