Title: Examples in XSB Prolog
1Examples in XSB Prolog
- ?pe?e??as?a ?a? ??apa??stas? G??s??
- ?????? 2010
- ?µ?µa ?p?st?µ?? ?p?????st?? ?a?ep?st?µ??? ???t??
2Typing a program on the XSB command line
- ? ???st?? t?? XSB ??e? t? d??at?t?ta ?a e?s??e?
t?? p??t?se?? (?e????ta ?a? ?a???e?) t??
p?????µµat?? t?? ???s?µ?p????ta? t? ??aµµ?
e?t???? t?? XSB, p.?. - ?- user. Enter mode to type predicates
rules. - Compiling user
- edge(1,2).
- edge(2,3).
- edge(2,4).
- reachable(X,Y) - edge(X,Y).
- reachable(X,Y) - edge(X,Z), reachable(Z, Y).
- end_of_file. Done with terminal mode
- user compiled, cpu time used 0.0500 seconds
- user loaded
- yes
3Loading a program in XSB
- ??e? ep?s?? t? d??at?t?ta ?a f??t?se? ??a
a??e?? p?? pe????e? t? ?????? p????aµµa. ??t? ?a
p??pe? ?a ??e? ?at????? .P - ?- edges. Load and run edges.P
- edges loaded
- yes
- G?a ?a f??t?se? ??a a??e?? p?? ß??s?eta? se
d?af??et??? directory ???fete - ?- source/edges. Load and run edges.P
which is saved in directory source - edges loaded
- yes
- To default directory ??a t?? XSB e??a? t?
- xsb-3.1-win32/config/x86-pc-windows/bin
- G?a ?a a???sete t? µ??e??? t?? ???s??a??de?? ????
st?? ??aµµ? e??a?e??? ? ???ep?????? ? ???ta?? ?
???e??? pa?a?????
4Making queries and termination
- ?- reachable(X,Y).X 1Y 2Â Type a
semi-colon repeatedlyX 2Y 3X 2Y
4X 1Y 3X 1Y 4no - ?- halt. Command to Exit XSBEnd XSB (cputime
0.15 secs, elapsetime 96.23 secs)
5Prolog Program Semantics
- ?a p?????µµata st?? Prolog µp????? ?a ??????
?ata???t? µe d?? t??p??? - d???t??? (declaratively)
- d?ad??ast??? (procedurally)
- ?ts? a? ?e???s??µe t?? p??tas?
- P - Q, R.
- a?t? µp??e? ?a e?µ??e?te? ?? e???
- ????t??? t? P e??a? a????? a? t? Q e??a? a?????
?a? t? R e??a? a????? - ??ad??ast??? G?a ?a ap?de???e? ?t? t? P e??a?
a?????, p??pe? p??ta ?a ap?de??? p??ta ?t? to Q
e??a? a????? ?a? st? s????e?a ?t? ?a? t? R e??a?
a?????.
6Loading a program in XSB
- ??a a??e?? µp??e? ?a pe????e?
- export declarations ??????? ta s?µß??a p??
µp????? ?a ???s?µ?p??????? ap? ???a a??e?a - local declarations ??????? ta s?µß??a µe t?p???
µ??? eµß??e?a - import declarations ep?t??p??? t? ???s? s?µß????
p?? ????? e?a??e? ap? ???a a??e?a - ?? d???se?? a?t?? µp????? ?a ?????? se
?p???d?p?te s?µe?? t?? p?????µµat?? ?a? ????? t??
a??????? µ??f? - - export sym1, ...,syml.
- - local sym1, ...,symm.
- - import sym1, ...,symn from module.
- ?p?? t? symi ??e? t? µ??f? functor/arity.
- p.?.
- - import reachable/2 from edges.
7Useful examples or , if-then-else
- ?? ?????? or µp??e?te ?a t? e?f??sete ?a? ??
e??? - or(A)- (A a A b ), write('A is a or b').
- ???s??? ?a µ?? ?e???te t?? pa?e???se??.
- if (X1) then write(b) else write(d)
- a(X)- write(a),
- ( X 1 -gt write(b) write(d) ),
- write(c).
8Useful examples - for
- ???s??? ?a µ?? ?e???te t?? s?????? te?µat?sµ??.
- Call with i(5) ? Result 4,3,2,1,0
- end condition Ngt0
- i(0).
- i(N) - Ngt0, write(N), nl, N1 is N-1, i(N1).
-
- Call with for(0,5) ? Result 0,1,2,3,4
- end condition StartltEnd
- for(End , End ).
- for(Start, End )- StartltEnd, write(Start), nl,
- Start1 is Start1, for(Start1,End).
9Dynamic Predicates
- ?at?????µata
- Stat??? (static) t??p?p?????ta? µ??? µe
reloading t?? p?????µµat??. - ???aµ??? (dynamic) µp????? ?a t??p?p??????? t??
??a p?? t???e? ??a p????aµµa. - G?a ?a µp????µe ?a ?e???st??µe µ?a d?µ? d??aµ???,
st?? a??? t?? p?????µµat?? ?????µe t? d???s? - - dynamic turn/1 ?
- - dynamic pred/2.
- St? s????e?a µp????µe ?a p??s??s??µe /
afa???s??µe ded?µ??a ap? t? ß?s? ???s?? µe ???s?
t?? - assert() e?s??e? ??a ??? ?e????? st? µ??µ?.
- retract() d?a???fe? ??a ?e????? ap? t? µ??µ?.
10XSB library modules List processing (1/3)
- append(?List1, ?List2, ?List3)
- module basics
- Succeeds if list List3 is the concatenation of
lists List1 and List2. - member(?Element, ?List)
- module basics
- Checks whether Element unifies with any element
of list List, succeeding more than once if there
are multiple such elements. - memberchk(?Element, ?List)
- module basics
- Similar to member/2, except that memberchk/2 is
deterministic, i.e. does not succeed more than
once for any call. - delete_ith(Index, List, ?Element, ?RestList)
- module listutil
- Succeeds if the ith element of the list List
unifies with Element, and RestList is List with
Element removed.
11XSB library modules List processing (2/3)
- ith(?Index, ?List, ?Element)
- module basics
- Succeeds if the ith element of the list List
unifies with Element. Fails if Index is not a
positive integer or greater than the length of
List. Either Index and List, or List and
Element, should be instantiated at the time of
the call. - length(?List, ?Length)
- module basics
- Succeeds if the length of the list List is
Length. - same_length(?List1, ?List2)
- module basics
- Succeeds if list List1 and List2 are both lists
of the same number of elements. - select(?Element, ?L1, ?L2)
- module basics
- List2 derives from List1 by selecting (removing)
an Element non-deterministically.
12XSB library modules List processing (3/3)
- reverse(List, ?ReversedList)
- module basics
- Succeeds if ReversedList is the reverse of list
List. If List is not a proper list, reverse/2
can succeed arbitrarily many times. It works only
one way. - perm(List, ?Perm)
- module basics
- Succeeds when List and Perm are permutations of
each other. The main use of perm/2 is to
generate permutations of a given list. Perm may
be partly instantiated. - subseq(?Sequence, ?SubSequence, ?Complement)
- module basics
- Succeeds when SubSequence and Complement are
both subsequences of the list Sequence (the
order of corresponding elements being preserved)
and every element of Sequence which is not in
SubSequence is in the Complement and vice versa.
- merge(List1, List2, ?List3)
- module listutil
- Succeeds if List3 is the list resulting from
merging lists List1 and List2
13Append example
append(,L,L). append(XL, M, XN) -
append(L,M,N).
append(1,2,3,4,X)?
14Append example
append(,L,L). append(XL,M,XN) -
append(L,M,N).
append(1,2,3,4,X)?
X1,L2,M3,4,AXN
15Append example
append(,L,L). append(XL,M,XN) -
append(L,M,N).
append(2,3,4,N)?
append(1,2,3,4,X)?
X1,L2,M3,4,AXN
16Append example
append(,L,L). append(XL,M,XN) -
append(L,M,N).
X2,L,M3,4,N2N
append(2,3,4,N)?
append(1,2,3,4,X)?
X1,L2,M3,4,A1N
17Append example
append(,L,L). append(XL,M,XN) -
append(L,M,N).
append(,3,4,N)?
X2,L,M3,4,N2N
append(2,3,4,N)?
append(1,2,3,4,X)?
X1,L2,M3,4,A1N
18Append example
append(,L,L). append(XL,M,XN) -
append(L,M,N).
append(,3,4,N)?
L 3,4, N L
X2,L,M3,4,N2N
append(2,3,4,N)?
append(1,2,3,4,X)?
X1,L2,M3,4,A1N
19Append example
append(,L,L). append(XL,M,XN) -
append(L,M,N).
A 1N N 2N
N L L 3,4 Answer A 1,2,3,4
append(,3,4,N)?
L 3,4, N L
X2,L,M3,4,N2N
append(2,3,4,N)?
append(1,2,3,4,X)?
X1,L2,M3,4,A1N
20Building new predicates - Range
- Create a list containing all integers within a
given range. - - export range/3.
- range(I,I,I).
- range(I,K,IL) - I lt K, I1 is I 1,
range(I1,K,L). - range(I,K,L) - I lt K, and L is the list
containing all - consecutive integers from I to K.
- ?.?.
- ?- range(4, 7, L).
- L 4,5,6,7
- no
-
21Building new predicates - Slice
- Extract a slice from a list.
- - export slice/4.
- slice(X_,1,1,X).
- slice(XXs,1,K,XYs) - K gt 1, K1 is K - 1,
- slice(Xs,1,K1,Ys).
- slice(_Xs,I,K,Ys) - I gt 1, I1 is I - 1, K1
is K - 1, - slice(Xs,I1,K1,Ys).
- slice(L1,I,K,L2) - L2 is the list of the
elements of L1 - between index I and index K (both included).
- ?.?.
- ?- slice(19,21,35,43,56,68,77,89.90, 3, 5,
L2). - L2 35,43,56
- no
22Building new predicates - Split
- Split a list into two parts.
- - export split/4.
- split(L,0,,L).
- split(XXs,N,XYs,Zs) - N gt 0, N1 is N -
1, split(Xs,N1,Ys,Zs). - split(L,N,L1,L2) - the list L1 contains the
first N elements - of the list L, the list L2 contains the
remaining elements. - ?.?.
- ?- split(1,2,3,4,5,6,7,8,9,10, 3, L1, L2).
- L1 1,2,3
- L2 4,5,6,7,8,9,10
- no
-
23Building new predicates - Rotate
- Rotate a list N places to the left.
- - import append/3 from basics.
- - import length/2 from basics.
- - import split/4 from split.
- - export rotate/3.
- rotate(L1,N,L2) - N gt 0, length(L1,NL1),
- N1 is N mod NL1, rotate_left(L1,N1,L2).
- rotate(L1,N,L2) - N lt 0, length(L1,NL1),
- N1 is NL1 (N mod NL1),
rotate_left(L1,N1,L2). - rotate_left(L,0,L).
- rotate_left(L1,N,L2) - N gt 0,
split(L1,N,S1,S2),append(S2,S1,L2). - rotate(L1,N,L2) - the list L2 is obtained
from the list L1 - by rotating the elements of L1 N places to the
left. - ?.?.
24Building new predicates Random Selection
- Extract a given number of randomly selected
elements from a list. - - import random/3 from random.
- - import length/2 from basics.
- - import delete_ith/4 from listutil.
- - export rnd_select/3.
- rnd_select(_,0,).
- rnd_select(X,1,X).
- rnd_select(Xs,N,XZs) - N gt 0, length(Xs,L),
random(1,L,I), - delete_ith(I,Xs,X,Ys),
- N1 is N-1, rnd_select(Ys,N1,Zs).
- rnd_select(L,N,R) - the list R contains N
randomly selected - items taken from the list L.
- ?.?.
- ?- rnd_select(1,2,3,4,5,6,7,8,9, 5, R).
- R 7,2,8,1,4
25Building new predicates Random Permutation
- Generate a random permutation of the elements of
a list. - - import length/2 from basics.
- - import rnd_select/3 from random_selection.
- - export rnd_permu/2.
- rnd_permu(L1,L2) - length(L1,N),
rnd_select(L1,N,L2). - rnd_permu(L1,L2) - the list L2 is a random
permutation of - the elements of the list L1.
- ?.?.
- ?- rnd_permu(1,2,3,4,5,6,7,8,9, L).
- L 7,3,5,1,8,2,4,6,9.
- no
-
26Eight Queens Problem
- ? st???? e??a? ?a t?p??et????? ??t? ßas???sse? se
µ?a s?a????a ????? ?a µp??e? ?a ape??e?ta? ??p??a
ap? ?p??ad?p?te ????. Ta p??pe? ep?µ???? ? ???e
ßas???ssa ?a ß??s?eta? se d?af??et??? ??aµµ?,
st??? ?a? d?a????? t?? s?a????a?. ? p??te???µe??
??s? ap?te?e? µ?a ?e???? ??s? ??a s?a????e? (?a?
a?t?st???? p????? ßas???ss??) ?p????d?p?te
µe??????. - ??apa??st??µe t?? ??se?? t?? ßas???ss?? µe µ?a
??sta t?? a???µ?? 1-?. G?a pa??de??µa ? ??sta
4,2,7,3,6,8,5,1 s?µa??e? ?t? ? ßas???ssa st??
p??t? st??? ß??s?eta? st? ??aµµ? 4, ? ßas???ssa
st? de?te?? st??? st? ??aµµ? 2. ?.?.?. ?e a?t??
t?? t??p? e?asfa?????µe ?t? ? ???e ßas???ssa
ß??s?eta? se d?af??et??? st??? ?a? ??aµµ?. ??
µ??? p?? ap?µ??e? e??a? ?a ???e? ? ??e???? t??
d?a??????. ??a ßas???ssa t?p??et?µ??? st? st??? ?
?a? ??aµµ? ? ?ata?aµß??e? d?? d?a???????, µ?a µe
a???µ? C XY ?a? µ?a µe a???µ? DX-Y.
27Eight Queens The Solution
- - import memberchk/2 from basics.
- - import range/3 from range.
- - import select/3 from basics.
- queens(N,Qs) - Qs is a solution of the
N-queens problem - queens(N,Qs) - range(1,N,Rs), permu(Rs,Qs),
test(Qs,1,,). - permu(,).
- permu(Qs,YYs) - select(Y,Qs,Rs),
permu(Rs,Ys). - test(Qs,X,Cs,Ds) - the queens in Qs,
representing columns X to - N, are not in conflict with the diagonals Cs
and Ds Cs and Ds keep - track of the already occupied diagonals.
- test(,_,_,_).
- test(YYs,X,Cs,Ds) -
- C is X-Y, \ memberchk(C,Cs),
- D is XY, \ memberchk(D,Ds),
- X1 is X 1,
28Knights Tour Problem
- ? st???? e??a? ?a ß???µe µ?a p??e?a p?? µp??e? ?a
d?a????e? ??a ????? se ??e? t?? ??se?? µ?a
s?a????a? a??a??et?? µe??????, ????? ?a
ep?s?efte? t?? ?d?a ??s? pa?ap??? ap? µ?a f????.
29Knights Tour The Solution (1/2)
- - import memberchk/2 from basics.
- knights(N,Knights) - Knights is a knight's
tour on a NxN chessboard - knights(N,Knights) - M is NN-1,
knights(N,M,1/1,Knights). - closed_knights(N,Knights) - Knights is a
knight's tour on a NxN - chessboard which ends at the same square where
it begun. - closed_knights(N,Knights) - knights(N,Knights),
Knights X/Y_, jump(N,X/Y,1/1). - knights(N,M,Visited,Knights) - the list of
squares Visited must be - extended by M further squares to give the
solution Knights of the - NxN chessboard knight's tour problem.
- knights(_,0,Knights,Knights).
- knights(N,M,Visited,Knights) -
- Visited X/Y_,
- jump(N,X/Y,U/V),
- \ memberchk(U/V,Visited),
30Knights Tour The Solution (2/2)
- jumps on an NxN chessboard from square A/B to
C/D - jump(N,A/B,C/D) -
- jump_dist(X,Y),
- C is AX, C gt 0, C lt N,
- D is BY, D gt 0, D lt N.
- jump distances
- jump_dist(1,2).
- jump_dist(2,1).
- jump_dist(2,-1).
- jump_dist(1,-2).
- jump_dist(-1,-2).
- jump_dist(-2,-1).
- jump_dist(-2,1).
- jump_dist(-1,2).
-
31?? p??ß??µa t?? ß?s???
- ?? p??ß??µa t?? ß?s??? ap?te?e? ??a ??ass???
p??ß??µa ??????? (puzzle). - Se µ?a ???? e??? p?taµ?? ?p?????? ??a? ß?s???,
??a? ????? ??a p??ßat? ?a? ??a deµ?t? sa???. ?
d?a??s?µ? ß???a ???? µ??? d?? a?t??e?µe?a ???e
f???. ?? ?p???s??µe ?t? se ???e st??µ? ? ?????
?a? t? p??ßat?, ?a??? ?a? t? p??ßat? ?a? t?
deµ?t? de? µp????? ?a e??a? µ??a t??? se µ?a ????
(????? t?? ß?s??), p??a e??a? ? a???????a
????se?? ? ?p??a p??pe? ?a ???e? ??a ?a pe??s???
???? ap??ta?t? - ?? pa?ap??? p??ß??µa e??a? ??s?ast??? ??a
p??ß??µa s?ed?asµ?? ????se?? (Planning). Sta
p??ß??µata t?? ?at?????a? a?t??, µ?a ??s? e??a? ?
a?a??t?s? st? ???? t?? ?atast?se?? t?? ??sµ?? t??
p??ß??µat??. ???e t?t??a ?at?stas? pe?????fe? t??
"??sµ?" t?? p??ß??µat?? t?? s???e???µ??? ???????
st??µ?. ?? µetaß?se?? ap? µ?a s???e???µ???
?at?stas? se µ?a ep?µe?? ?????ta? µ?s? te?est??.
32?p????? ??apa??stas??
- ???a? p????? ?? d?a??s?µe? ep?????? µe t?? ?p??e?
µp????µe ?a a?apa?ast?s??µe t? s???e???µ???
p??ß??µa. ? pa?a??t? ???p???s? ???s?µ?p??e? ??a
t?? pe????af? t?? ?at?stas?? ??a s???eto ??? t??
µ??f?? - state(shepherd(A),sheep(B),wolf(C),hey(D))
- ?p?? ta A, B, C, D e??a? ?? ???e? st?? ?p??e?
ß?????ta? a?t?st???a ? ß?s???, t? p??ßat?, ?
????? ?a? t? deµ?t? sa???. - ?e ß?s? t?? pa?ap??? a?apa??stas? ??????ta? ??
te?est??, p?? a?t?st?????? ??s?ast??? st??
????se?? p?? µp????? ?a ?????? ??a ?a ???e? t?
p??ß??µa.
33???sµ?? ?at?????µ?t??
- ?? ?at?????µa move/3 pe?????fe? t?? ep?t?ept??
????se?? p?? µp????? ?a ??????. ? µetaß??t?
State e??a? ? "t?????sa" ?at?stas?, ? µetaß??t?
Move e??a? ? ????s? p?? ?aµß??e? ???a ??a ?a
p?????e? ? ??a ?at?stas? p?? e??p??e?ta? µe t??
µetaß??t? NewState. -
- move/3
- move(State,Move,NewState)
- Move the shepherd
- move(state(shepherd(X1),sheep(S),wolf(W),hey(H)),
go_to_other_shore(X1,X2), state(shepherd(X2),shee
p(S),wolf(W),hey(H)))- opposite(X1,X2). - Take the sheep to the other side
- move(state(shepherd(X1),sheep(X1),wolf(W),hey(H))
, move_sheep(X1,X2), state(shepherd(X2),sheep(X2),
wolf(W),hey(H)))- opposite(X1,X2).
34???sµ?? ?at?????µ?t??
- Take the wolf to the other side
- move(state(shepherd(X1),sheep(S),wolf(X1),hey(H))
, move_wolf(X1,X2), state(shepherd(X2),sheep(S),wo
lf(X2),hey(H)))- opposite(X1,X2). - Take the hey to the other side
- move(state(shepherd(X1),sheep(S),wolf(W),hey(X1))
, move_hey(X1,X2), state(shepherd(X2),sheep(S),wol
f(W),hey(X2)))- opposite(X1,X2). - ?? ?at?????µa opposite/2 d????e? t?? d?? ap??a?t?
???e?. - opposite/2
- opposite(X1,X2).
- opposite(a,b).
- opposite(b,a).
35???sµ?? ?at?????µ?t??
- ?? ?at?????µa is_valid/1 pet??a??e? ?ta? ?
?at?stas? State e??a? ep?t?ept?, d??ad? de?
pa?aß???e? t??? pe?????sµ??? t?? p??ß??µat??.. -
- is_valid/1
- is_valid(State).
- is_valid(state(shepherd(X),sheep(X),wolf(_),hey(_)
)). - is_valid(state(shepherd(X),sheep(_),wolf(X),hey(X)
)).
36???sµ?? ?at?????µ?t??
- ?? ?at?????µa end_state/1 pet??a??e? ?ta? ? State
e??a? ? te???? ?at?stas?, d??ad? ??a ta
a?t??e?µe?a e??a? st?? ???? b (?e????µe ?t?
a????? ??a ta a?t??e?µe?a e??a? st?? ???? a). -
- end_state/1
- end_state(State).
- end_state(state(shepherd(b),sheep(b),wolf(b),hey(b
))).
37???sµ?? ?at?????µ?t??
- ?? ?at?????µa solve/3 ß??s?e? t?? se??? t??
????se?? p?? p??pe? ?a ?????? ??a ?a ep????e? t?
p??ß??µa. ??s?ast??? ? a??????µ?? a?a??t?s?? p??
???s?µ?p??e?ta? e??a? ? ?ata-ß???? a?a??t?s? t??
Prolog. - ? µetaß??t? State e??a? ? "t?????sa" ?at?stas?, ?
µetaß??t? Moves ? ??sta t?? ????se?? ?a? ?
Previous_States ? ??sta t?? ?atast?se?? t??
?p??e? ??e? "ep?s?e?te?" µ???? t??a ? d?ad??as?a
a?a??t?s??. - ???e ??a ?at?stas? p?? p????pte? (NextState), de?
p??pe? ?a a???e? st?? ??sta a?t? ??a t?? ap?f???
ß?????. -
- solve/3
- solve(State,Moves,Previous_States)
- solve(State,,_)- end_state(State).
- solve(State,MoveMoves,Previous_States)-
- move(State,Move,NextState),
- \ member(NextState,Previous_States),
- is_valid(NextState),
- solve(NextState,Moves,NextStatePrevious_States
).
38???sµ?? ?at?????µ?t??
- ?? ep?µe?? ?at?????µa t?p??e? st?? ????? ta µ???
µ?a? ??sta?, ?a? ???s?µ?p??e?ta? ??a ?a t?p??e?
t?? ????se?? st?? ?????. -
- pretty_write/1
- pretty_write(List)
- pretty_write().
- pretty_write(FirstRest)- write(' -gt '),
write(First), nl, - pretty_write(Rest).
- ?? ?at?????µa run/1, ???s?µ?p??e?ta? ??a ?a
e?te??s??µe t? p????aµµa. -
- run(Moves)-solve(state(shepherd(a),sheep(a),wolf(
a),hey(a)),Moves, - state(shepherd(a),sheep(a),wolf(a),hey(a))),
- pretty_write(Moves),nl.
39?s??se??
- (as?.1) ??µ??????ste d?ad??as?a factorial p?? ?a
?p??????e? t? pa?a???t??? e??? a???µ??. ?.?. - ?- factorial(4,X).
- X24
- (as?.2) ??µ??????ste d?ad??as?a median p?? ?a
?p??????e? t?? µesa?? µ?a? ??sta? p?? pe????e?
a???µ??? pe??tt?? p??????. ?.?. - ?- median(2,8,6,4,7,9,3,X).
- X6
- (as?.3) ??µ??????ste d?ad??as?a set_equality p??
?a e????e? a? d?? ??ste? pe??????? ta ?d?a
st???e?a (de? µa? e?d?af??e? ? se??? p?? ?????
st? ??sta). ?.?. - ?- set_equality(1,2,3,3,1,2).
- yes
- ?- set_equality(1,2,3,3,1).
- no
40?s??se??
- (as?.4) ??ste t? p??ß??µa t?? ?e?ap?st???? µe
t??? ?a??ßa????. -
- ?e????af? p??ß??µat??
- St?? ???e? e??? p?taµ?? ?p?????? s??????? t?e??
?e?ap?st???? ?a? t?e?? ?a??ßa??? ?ts? ?ste se
???e ???? ?a ?p???e? ?s?? a???µ?? ?e?ap?st????
?a? ?a??ß????. ?p?s??, ?p???e? ?a? µ?a ß???a se
µ?a ap? t?? ???e?. T????µe ???? ?a µetafe????? se
µ?a ????. ?µ??, ? ß???a ??a ?a ?????e? ??e???eta?
t??????st?? ??a ?t?µ?, ???? µ??? µ???? d?? ?t?µa
?a? se ?aµ?a pe??pt?s? de? p??pe? ? a???µ?? t??
?a??ß???? ?a e??a? µe?a??te??? ap? a?t?? t??
?e?ap?st???? se ??p??a ????. - nice link
- http//gym-tsepel.ioa.sch.gr/play/problem2.htm