Snitt Implementera negation med snitt, not/1 Exempel

Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Intro
Mer om snitt
Idag
•
•
•
Intro
Snittexempel
Generera och testa
CLP
Exempel
Senast: Negationer
virginBirth(X) :mother(_, X), \+ father(_, X).
Snittexempel
Generera och testa
Villkorsprogrammerings (CLP)
Mer om snitt
Snittexempel
Generera och testa
CLP
| ?- virginBirth(X).
X = anakin ?
yes
Exempel
Intro
Mer om snitt
Syntax för negation
Snittexempel
Generera och testa
CLP
Exempel
Senast: Snitt
• Snitt (eng: cut) begränsar ”backtracking”:
• Exempel:
Har vi hittat en lösning så är det bra.
sibling(X,Y) :- parent(Z, X),parent(Z, Y),
woman(Z), \+ X=Y.
permSort(X, Y) :permutation(X, Y), ordered(Y), !.
• not skrivs \+.
• I lådmodellen:
Call
permSort
permutation
\+ X=Y
ordered
Exit
!
X=Y
• Gröna snitt: Påverkar inte programmets
Fail
Intro
Mer om snitt
S
S
Snittexempel
Generera och testa
funktion.
• Röda snitt: Förändrar programmets logiska
läsning.
Redo
CLP
Exempel
Intro
Implementera negation med snitt,
not/1
• Hjälp: call/1: Försöker lösa det mål som
ges som argument:
|?- call(disjoint([1,2,3], [4,5,6])).
yes
• Hjälp: fail/0: Mål som alltid misslyckas.
• Lösning för not/1:
not(X) :- call(X), !, fail.
not(X).
(I princip samma för \+)
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempelprogram: Sortera gener
Exempel
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel: if-then-else
(Från Sterling&Shapiro)
Konstruktiv användning av rött snitt:
ifThenElse(P, Q,
ifThenElse(_, _,
| ?- X=5,
ifThenElse(X<10,
hello
X = 5 ?
yes
| ?- X=11,
ifThenElse(X<10,
goodbye
X = 11 ?
yes
| ?Intro
Mer om snitt
_) :- call(P), !, call(Q).
R) :- call(R).
write(hello), write(goodbye)).
write(hello), write(goodbye)).
Snittexempel
Generera och testa
CLP
Ett beräkningsproblem
• Vitt skilda organismer har mycket lika
• Antalet inversioner är proportionellt mot
genuppsättning
• Genordning ofta delvis bevarad!
• Betrakta ett genom:
• Hur många inversioner har krävts för att
1
5
2
3
4
• Se genomet som en permutation av gener:
(1, 2, 3, 4, 5)
• Liknande genom:
(1, 4, 3, 2, 5)
• En inversion byter ordning på en
delsekvens.
Exempel
tiden sedan artdelningen.
komma från ett genom till ett annat?
• Heuristik: Plocka bort brytpunkter.
• Brytpunkt: När två intilliggande gener inte
har närliggande tal
1|4 3 2|5
12345
Exempel
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Intro
Mer om snitt
Snittexempel
Heuristiken
Generera och testa
CLP
Exempel
Huvudprogram
Basfall:
• Om n gener, lägg till 0 och n + 1:
sortByInversions(L, []) :countBreakpoints(L, N), N=0.
5, 4, 3, 2, 1 ⇒ 0, 5, 4, 3, 2, 1, 6
Rekursion:
• Om det finns en inversion som plockar bort
sortByInversions(Perm, [NextPerm|StateList]) :removeBreakpoints(Perm, NextPerm),
sortByInversions(NextPerm, StateList).
två brytpunkter, ta den.
• Annars, om det finns en inversion som
plockar bort en brytpunkt, ta den.
• Iterera tills inga fler brytpunkter.
Hjälppredikat:
removeBreakpoints(L, NextL) :findInversionTwo(L, NextL), !.
removeBreakpoints(L, NextL) :findInversionOne(L, NextL).
Obs: Ej optimalt!
Alltför beräkningskrävande att lösa optimalt
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Testfall
Intro
9, 2, 1, 6, 5, 4, 3, 8, 7, 10
1, 2, 9, 6, 5, 4, 3, 8, 7, 10
1, 2, 3, 4, 5, 6, 9, 8, 7, 10
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Snittexempel
Generera och testa
Generera och testa
CLP
Exempel
Indata: Resultat x1 , x2 , . . . , xk från k kast.P
Kast i ger poäng pi . En serie har poäng ki=1 pi .
Regler:
1. Strajk: Om i < k och xi = 10 räknas
påföljande två kast dubbelt.
2. Strajk sist: Om i = k och xi = 10 är pi = 20.
3. Annars är pi = xi .
Beräkna poängen!
| ?- p4(X), inversions(X, N).
.9.1........
...96.43....
.......9.7..
N = 3,
X = [9,2,1,6,5,4,3,8,7,10] ?
yes
Mer om snitt
Snittexempel
Generaliserad bowling: Räkna poäng
Genom A: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Genom B: 9, 2, 1, 6, 5, 4, 3, 8, 7, 10
Intro
Mer om snitt
CLP
Exempel
Intro
Mer om snitt
Snittexempel
Exempelräkning
Generera och testa
CLP
Exempel
Lösning
bowling([], 0).
Serie: 10, 2, 3
Poäng: 10 + 2 + 3 + 2 + 3 = 20
bowling([10], 20) :- !.
bowling([10, X2, X3 | Tail], P) :P is 10 + X2 + X3 + PT,
bowling([X2, X3 | Tail], PT), !.
Serie: 5, 10
Poäng: 5 + 2 × 10 = 25
bowling([10, X2 | Tail], P) :P is 10 + X2 + PT,
bowling([X2 | Tail], PT), !.
Serie: 10, 10, 5, 10
Poäng:
10 + 10 + 5 + 10 + 5 + 10 + 5 + 2 × 10 = 75
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
bowling([X | Tail], P) :P is X + PT,
bowling(Tail, PT).
Exempel
Intro
Mer om snitt
Snittexempel
Generera och testa
searchProblem(X) :generate(X),
testSolution(X).
• Används i lab L2.
CLP
Sudoku
6 8 7
• Programstruktur:
Generera och testa
9
8 Placera ut
siffrorna 1 – 9 så
6
2
4
att varje siffra
4
3
återfinns endast
3
7
6
en gång i varje
rad, kolumn, och
9
7
3 1 delkvadrat.
9
3 6 8
1 2
9
Exempel
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Intro
Datastruktur för Sudoku
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Ansats med generera/testa
sudoku(S) :transform(S, ByColumn, BySubsquare),
verifyLists(S),
verifyLists(ByColumn),
verifyLists(BySubsquare).
Lista av rader
[[X11,X12,X13,X14,X15,X16,X17,X18,X19],
[X21,X22,X23,X24,X25,X26,X27,X28,X29],
[X31,X32,X33,X34,X35,X36,X37,X38,X39],
[X41,X42,X43,X44,X45,X46,X47,X48,X49],
[X51,X52,X53,X54,X55,X56,X57,X58,X59],
[X61,X62,X63,X64,X65,X66,X67,X68,X69],
[X71,X72,X73,X74,X75,X76,X77,X78,X79],
[X81,X82,X83,X84,X85,X86,X87,X88,X89],
[X91,X92,X93,X94,X95,X96,X97,X98,X99]]
verifyLists([]).
verifyLists([L|Ls]) :verifyList(L),
verifyLists(Ls).
verifyList(L) :permutation([1,2,3,4,5,6,7,8,9], L).
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Intro
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
• Testning snabbt (”är detta en sudoku?”)
[[X11,X21,X31,X41,X51,X61,X71,X81,X91],
[X12,X22,X32,X42,X52,X62,X72,X82,X92],
[X13,X23,X33,X43,X53,X63,X73,X83,X93],
[X14,X24,X34,X44,X54,X64,X74,X84,X94],
[X15,X25,X35,X45,X55,X65,X75,X85,X95],
[X16,X26,X36,X46,X56,X66,X76,X86,X96],
[X17,X27,X37,X47,X57,X67,X77,X87,X97],
[X18,X28,X38,X48,X58,X68,X78,X88,X98],
[X19,X29,X39,X49,X59,X69,X79,X89,X99]],
X21,X22,X23,
X24,X25,X26,
X27,X28,X29,
X51,X52,X53,
X54,X55,X56,
X57,X58,X59,
X81,X82,X83,
X84,X85,X86,
X87,X88,X89,
Snittexempel
Hur funkar det?
transform([[X11,X12,X13,X14,X15,X16,X17,X18,X19],
[X21,X22,X23,X24,X25,X26,X27,X28,X29],
[X31,X32,X33,X34,X35,X36,X37,X38,X39],
[X41,X42,X43,X44,X45,X46,X47,X48,X49],
[X51,X52,X53,X54,X55,X56,X57,X58,X59],
[X61,X62,X63,X64,X65,X66,X67,X68,X69],
[X71,X72,X73,X74,X75,X76,X77,X78,X79],
[X81,X82,X83,X84,X85,X86,X87,X88,X89],
[X91,X92,X93,X94,X95,X96,X97,X98,X99]],
[[X11,X12,X13,
[X14,X15,X16,
[X17,X18,X19,
[X41,X42,X43,
[X44,X45,X46,
[X47,X48,X49,
[X71,X72,X73,
[X74,X75,X76,
[X77,X78,X79,
Mer om snitt
• Långsamt att lösa en sudoku!
• Klarar bara ett litet antal okända (klarar inte
ICAs ”enkla” sudoku med 45 okända)
• ”17 okända går på några sekunder”
X31,X32,X33],
X34,X35,X36],
X37,X38,X39],
X61,X62,X63],
X64,X65,X66],
X67,X68,X69],
X91,X92,X93],
X94,X95,X96],
X97,X98,X99]]).
Generera och testa
• Vad göra?
• Generera smartare!
CLP
Exempel
Intro
Mer om snitt
Färga en karta
Snittexempel
Generera och testa
CLP
Exempel
Datastruktur
region(Area, AreaColor, NeighborColors).
• Sats: Varje planär graf kan färgas med fyra
Exempelinstans:
färger.
• Alltså: Varje karta kan färgas med fyra
färger.
• Skriv ett program som färgar en karta!
[region(a,
region(b,
region(c,
region(d,
region(e,
region(f,
(Från Sterling-Shapiro: The Art of Prolog)
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
En bit av Europa
%
färg,
map(europe,
[region(portugal, P,
region(spain,
E,
region(france,
F,
region(belgium,
B,
region(holland,
H,
region(germany,
G,
region(luxembourg,L,
region(italy,
I,
region(switzerl, S,
region(austria,
A,
).
grannars färger
[E]),
[F, P]),
[E, I, S, B, G, L]),
[F, H, L, G]),
[B, G]),
[F, A, S, H, B, L]),
[F, B, G]),
[F, A, S]),
[F, I, A, G]),
[I, S, G])])
Intro
Mer om snitt
A,
B,
C,
D,
E,
F,
[B,C,D]),
[A, C, D]),
[A,B,D,E,F]),
[A,C, F]),
[B, C, F]),
[C, D, E])]
Snittexempel
Generera och testa
CLP
Exempel
Programmet
% colorMap(Map, ColorList)
% För varje region: Välj en färg
colorMap([],_).
colorMap([Region|Regions], Colors) :colorRegion(Region, Colors),
colorMap(Regions, Colors).
% colorRegion(Region, ColorList)
% En region tar en färg och kräver att grannregionerna
% inte använder den färgen
colorRegion(region(Name,
Color,
Neighbors), Colors) :select(Color, Colors, Colors1), %Generera
members(Neighbors, Colors1).
%Testa
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Intro
Mer om snitt
Exempelkörning
Snittexempel
Generera och testa
CLP
Exempel
Om programmet
| ?- map(europe, M),
colorMap(M, [red,blue,green,yellow]).
M = [region(portugal,red,[blue]),region(spain,blue,[red,red]),region(france,red,[blue,blue,green,blue,yellow,green]),r
egion(belgium,blue,[red,red,green,yellow]),region(holland,red,[blue,yellow]),region(germany,yellow,[red,red,green,red|
...]),region(luxembourg,green,[red,blue,yellow]),region(italy,blue,[red,red|...]),region(switzerl,green,[red|...]),reg
• Implementerar en snål algoritm.
ion(...)] ?
yes
• Riskerar vara ineffektiv.
| ?- map(europe, M),
• Fler färger ⇒ snabbare
colorMap(M, [red,blue,green]).
no
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Intro
Mer om snitt
CLP
Snittexempel
Generera och testa
CLP
Exempel
Bakgrund
Constraint Logic Programming
Två typproblem:
1. Hitta tilldelning på X så att villkoren
C uppfylls
2. ... och maximerar f (X ).
Logikvillkorsprogrammering
Tillämpning: Constraint Satisfaction Problems
Notera: ”Programmering” ≈ planering!
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Intro
• Sudoku: Hitta tilldelning på elementen i X
Snittexempel
Generera och testa
Generera och testa
CLP
Exempel
• Samma grundproblem återkommer
så att rader, kolumner, och nio delkvadrater
är unika element.
• SL: Vilken är den snabbaste vägen från
Fridhemsplan till KTH som går via
Karlaplan?
• Genomik: Givet 4, 2 × 107 läsningar av
DNA, delvis och slumpvis överlappande,
vilket är den kortaste sammanfogningen?
Mer om snitt
Snittexempel
Typproblem ⇒ typlösningar
Exempelproblem
Intro
Mer om snitt
CLP
Exempel: Linjärprogrammering
• Samma lösningstekniker återanvänds
• Kan vi standardisera?
Ja: Standardalgoritmer
Ja: Standardisera även
programmeringsmetodiken.
Varför återimplementera
algoritmer?
Exempel
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Exempel: Linjärprogrammering
Maximera 7x1 + 2x2 − x3 då
x1 + x2 ≤ 7
x1 + 2x3 ≥ 11
Maximera cx då Mx ≤ b och x ≥ 0.
och
c = (7, 2, −1), M =
x1 ≥ 0, x2 ≥ 0, x3 ≥ 0
eller allmänt:
maximera cx
då Mx ≤ b.
Kan du formulera ditt optimeringsproblem på
denna form?
1 1 0
1 0 2
, b=
7
−11
Algoritmer:
Simplex: Icke-polynomiell, men enkel och
praktisk.
Inrepunktsmetod: Polynomiell, praktisk
Utbytbara lösare på samma formulering!
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Intro
Mer om snitt
Olika områden
Snittexempel
Generera och testa
CLP
Exempel
Klassiskt problem
• Linjärprogrammering
Telegram: SEND+MORE=MONEY
Hur många kronor behövdes?
• Semidefinit programmering
• Icke-linjär programmering
S E N D
+ M O R E
M O N E Y
• Linjär heltalsprogrammering
• Boolsk villkorsprogrammering
• CP över ändliga domäner
Variablerna S, E, N, D, M, O, R, Y tar värden
ur {0, 1, . . . , 9}.
Domänen skiljer!
Vi tittar på ändliga domäner (finite domains).
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Intro
Mer om snitt
Mål
Snittexempel
Generera och testa
CLP
• Måste ange den ändliga domänen för varje
domänvariabel.
• Domänvariabler ingår i relationer.
• Relationer anslås (are posted) till en lösare.
Exempel
Intro
Mer om snitt
:10*N + D
10*R + E
10*E + Y.
Snott och anpassat från Sicstus-manualen
Snittexempel
Generera och testa
CLP
Exempel
Ange variabeldomän:
• fd_domain(Xs, Min, Max):
Variablerna i Xs ska ligga i
{M in, M in + 1, . . . , M ax}.
Ex:
fd_domain([S,E,N,D,M,O,R,Y],0,9)
• fd_domain(Team, [aik,dif,hif]),
m.m.
Bivillkor:
• A + B #> 0,
• 4*X + 7 * Y #= 0,
och andra linjära uttryck.
mm([S,E,N,D,M,O,R,Y]) :fd_domain([S,E,N,D,M,O,R,Y], 0, 9),
S#>0, M#>0,
fd_all_different([S,E,N,D,M,O,R,Y]),
summera(S,E,N,D,M,O,R,Y),
fd_labeling([S,E,N,D,M,O,R,Y]).
summera(S, E, N, D, M, O, R, Y)
1000*S + 100*E +
+
1000*M + 100*O +
#= 10000*M + 1000*O + 100*N +
Snittexempel
Predikat för CLP
S E N D
+ M O R E
M O N E Y
Mer om snitt
Exempel
• Kan ha ”vanliga” Prologvariabler
Klassikern i CLP
Intro
CLP
• Vi optimerar/löser över domänvariabler.
• Formellt språk för optimeringsproblem
• Inbyggda generella sökheuristiker
• Generella algoritmer en utopi
• ”Förvånansvärt stora satisfierbarhetsproblem
kan lösas idag”
Mer om snitt
Generera och testa
Grunder i CLP
• Formellt språk för sökproblem
Intro
Snittexempel
Generera och testa
CLP
Exempel
Intro
Mer om snitt
Fler predikat för CLP
Snittexempel
Generera och testa
CLP
Tilldelningspredikat
• fd_labeling(Vars, Opts).
Kombinatoriska villkor:
• fd_all_different(L).
Alla domänvariabler i L har olika värden.
• fd_atleast(N, Xs, V).
Minst N variabler i listan Xs har värdet V . Vi
har också fd_atmost och fd_exactly.
• fd_cardinality(Constr, Count).
Sätt Count till antalet uppfyllda villkor i
listan Constraints. T.ex.,
fd_cardinality([X#=0,Y#=0,Z#=0], Count)
räknar antalet nollvärda variabler.
Hitta värden för domänvariabler i Vars. Val
med Opts:
•
•
Hur välja “nästa” variabel?
Hur välja dess värde?
Enklast:
fd_labeling(Xs).
“Hitta en tilldelning av värden Xs enligt
givna villkor.”
• fd_minimize(Goal, Var).
• fd_maximize(Goal, Var).
Anropa Goal och använd
“branch-and-bound” för att
minimera/maximera värdet på Var.
Exempel
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Exempel
Intro
Mer om snitt
Snittexempel
Sudoku igen
Generera och testa
CLP
Sudoku igen
• Indata: Matris som lista av rader.
• Indata: Matris som lista av rader.
• Predikat transform för att växla rader till
• Predikat transform för att växla rader till
kolumner till delkvadrater:
transform(R,C,S).
kolumner till delkvadrater:
transform(R,C,S).
R = [[X11,X12,X13,X14,X15,X16,X17,X18,X19],
[X21,X22,X23,X24,X25,X26,X27,X28,X29],
[X31,X32,X33,X34,X35,X36,X37,X38,X39],
[X41,X42,X43,X44,X45,X46,X47,X48,X49],
[X51,X52,X53,X54,X55,X56,X57,X58,X59],
[X61,X62,X63,X64,X65,X66,X67,X68,X69],
[X71,X72,X73,X74,X75,X76,X77,X78,X79],
[X81,X82,X83,X84,X85,X86,X87,X88,X89],
[X91,X92,X93,X94,X95,X96,X97,X98,X99]]
Intro
Mer om snitt
Snittexempel
Exempel
Generera och testa
CLP
Exempel
C = [[X11,X21,X31,X41,X51,X61,X71,X81,X91],
[X12,X22,X32,X42,X52,X62,X72,X82,X92],
[X13,X23,X33,X43,X53,X63,X73,X83,X93],
[X14,X24,X34,X44,X54,X64,X74,X84,X94],
[X15,X25,X35,X45,X55,X65,X75,X85,X95],
[X16,X26,X36,X46,X56,X66,X76,X86,X96],
[X17,X27,X37,X47,X57,X67,X77,X87,X97],
[X18,X28,X38,X48,X58,X68,X78,X88,X98],
[X19,X29,X39,X49,X59,X69,X79,X89,X99]]
Intro
Mer om snitt
Sudoku igen
Snittexempel
Generera och testa
CLP
Exempel
Huvudprogram
• Indata: Matris som lista av rader.
81 variabler i Xs
• Predikat transform för att växla rader till
kolumner till delkvadrater:
transform(R,C,S).
S = [[X11,X12,X13,
[X14,X15,X16,
[X17,X18,X19,
[X41,X42,X43,
[X44,X45,X46,
[X47,X48,X49,
[X71,X72,X73,
[X74,X75,X76,
[X77,X78,X79,
Intro
Mer om snitt
Snittexempel
X21,X22,X23,
X24,X25,X26,
X27,X28,X29,
X51,X52,X53,
X54,X55,X56,
X57,X58,X59,
X81,X82,X83,
X84,X85,X86,
X87,X88,X89,
Generera och testa
sudoku(ByRow) :flatten(ByRow, Xs),
fd_domain(Xs, 1,9),
transform(ByRow, ByCol, ByQuad),
distinct_rows(ByRow),
distinct_rows(ByCol),
distinct_rows(ByQuad),
fd_labeling(Xs).
X31,X32,X33],
X34,X35,X36],
X37,X38,X39],
X61,X62,X63],
X64,X65,X66],
X67,X68,X69],
X91,X92,X93],
X94,X95,X96],
X97,X98,X99]])
CLP
Exempel
Intro
Mer om snitt
Hjälppredikat
Snittexempel
Generera och testa
CLP
Exempel
Sudokuresultat
sm05([[6,
[3,
[_,
[_,
[_,
[8,
[_,
[9,
[_,
distinct_rows([]).
distinct_rows([R|Rest]) :fd_all_different(R),
distinct_rows(Rest).
7,
_,
_,
_,
_,
_,
_,
4,
_,
_,
_,
_,
7,
_,
5,
_,
_,
_,
_,
_,
_,
1,
_,
_,
_,
2,
7,
_,
_,
8,
_,
4,
_,
6,
_,
_,
1,
9,
_,
_,
_,
6,
_,
_,
_,
_,
_,
_,
9,
_,
4,
_,
_,
_,
_,
8,
_,
_,
_,
_,
_,
_,
4,
_],
6],
_],
3],
_],
_],
_],
7],
1]]).
| ?- sm05(X), sudoku(X).
X = [[6,7,8,4,3,1,2,9,5],[3,1,4,5,2,9,7,
• 56 okända enkelt
• Hur så fort?
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Grundmetod
1.
2.
3.
4.
Välj en obunden domänvariabel Xi
Tilldela ett värde från domänen D(Xi )
Verifiera bivillkor som använder Xi
Om inga fler obundna domänvariabler:
Klart!
5. Annars, gå till 1.
Exempel
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Frågeställningar
• Hur välja nästa variabel?
Standardval: Variabler i turordning.
• Vilka konsekvenser har en tilldelning?
Ignoreras.
• Kan man undvika ”dåliga” tilldelningar?
Nej.
Standardalgoritmen är naiv!
... som alla heuristiker!
Exempel
Intro
Mer om snitt
Snittexempel
Generera och testa
CLP
Avslutningsvis
• Svåra problem är svåra.
• Ingen heuristik är alltid bra.
• System för villkorsprogrammering även i
andra språk.
Kurs: ID2204 Villkorsprogrammering, med
Christian Schulte.
Exempel