CS Challenge 12, The X Calculus
- Beregming er informations-repræsentations-transformation
- Man kan klare sig med ganske lidt
Turing-maskinen blev
udviklet i 1936 af
Alan Turing
som et (negativt) svar på
Hilberts berømte
Entscheidungsproblem
fra år 1900. Dette skete længe før
man byggede faktiske, fysiske computere, men de basale ideer
i Turing-maskinen (hukommelse,
instruktioner, sekventiel udførelse, tilstandsændringer)
er stadig arkitekturen for alle moderne computere.
Bemærkelsesværdigt blev problemet
også i 1936 løst helt uafhængigt af
Alonzo Chruch, med en på mange
måder mere elegant model for beregninger.
I denne Challenge ser vi på en meget abstrakt formulering af dette af
Haskell Curry fra ca. 1952.
Et program er et binært træ med
symbolet X i alle blade. Det vil sige, at
programmet faktisk kun er repræsenteret som faconen
af træet. Det beregningsmæssige indhold er
defineret ved, at der på runtime laves omskrivninger
(kaldet reduktioner)
i træet. På runtime kan der yderligere optræde
symbolerne S, K og
I som blade, efter disse regler:
- X a → a K S K
- S a b
c →
(a c)
(b c)
- K a b →
a
- I a → a
Der er altid tale om binære træer, så fx
a K S K
skal læses som
((a K) S) K.
Man kan se, at X-symbolerne hurtigt forsdvinder, og at
resultatet altid er et SKI-træ. Til gemgæld kan
SKI-træer præsenteres som X-tr%aelig;er, da der gælder
disse ligninger:
- K = (XX)X
- S = X(XX)
- I = SKK
Generelt har vi såldes
SKIX-træer, kan
nøjes med SKI-træer,
og bruger ehentlig kun X-træer for
at imponere - et rent binært træ er en meget
abstrakt formulering af et program!
Lige nu kan vi kun stirre undrende på vores
sprog og vores runtime: hvordan kan denne maskine benyttes til
at foretage fornuftige beregninger? Men situationen er egentlig ikke anderledes,
end hvis nogen gav os en ukendt computer uden software: vi kan skrive et langt
bitmønster i hukommelsen, og på runtime
ændrer dette sig til et andet bitmønster.
I begge tilfælde skal vi repræsentere vores
information på en så sneedig
måde, at den transformeres som beregninger.
Toolet X.java implementerer denne maskine.
Jommandoen:
java X run
læser et SKIX-træ fra
stdin, foretager alle reduktioner og udskriver
resultatet på stdout. Dem næste reduktion, der vælges,
er altid den højest oppe i træet og
læmgst til venstre.
Dette vslg gør SKIX til et
lazy sprog (hvorfor?).
Varianten:
java X trace
udskriver også mellemresultatet efter hver reduktiion.
Spørgsmål A
Forklar, at man i metoden reduceS kan se, at
implementationen faktisk tillader delte undertræer.
Giv et uformelt argument for, at dette ikke æmdrer
resultatet og nogle gange er hurtigere. Hint: SKIX er
et pure sprog.
Ikke-negative heltal kan udtrykkes på følgende
må, gcor [E] generelt angiver
indkodningen af et udtryk E:
- [0] = zero
- [n+1] = succ[n]
hvor vi benytter forkortelserne:
- zero = KI
- succ = S((S(KS))K)
Det snedige ved denne indkodning er, at:
Det
vil sige, et tal faktisk indkodes som en
for-løkke med dette antal
iterationer.
Toolet understøtter også
kommandoen:
java X translate
der oversætter et SKIX-udtryk
(fra stdin) med brug af numeraler og forskellige
andre konstanter til et rent X-udtryk
(på stdout). Endeligt vil kommandoen;
java X constant
tage et AKIX-udtryk (fra stdin)
og udskrive det tilsvarende numeral
(på stdout), hvis udtrykket faktisk er
indkodningen af et sådant.
Med tilstrækkelig snedighed kan man også finde
udtrk for andre aritmetiske operationer, som:
-
plus = SI(K(S(S(KS)K)))
-
mult = S(S(KS)(S(K(SI))(S(KK)(SI(K(S(S(KS)K)))))))(K(K(KI)))
der også understøttes af translate
kommandoen (afprøv dem!).
Spørgsmål B
Udfør et antal eksperimenter af formen:
echo "n m" | java X translate > foo
java X run < foo > bar
java X constant < bar
for forskellige (små) heltal
n og m.
Find på en hypotese om, hvad
[n][m]
generelt beregner.
Toolet bruger ofte meget stakplads i Java, men denne kan forøges til
fx 4MB ved at bruge option -Xss4m til
java kommandoen.
Booleans indkodes med disse udtryk:
De indkoder direkte en if-sætning, da:
- true a b → a
- false a b → b
Mu kan vi også finde en iszero funktion på
numeraler. Den udnytter at n er en
for-løkke til
n gange at anvende den konstante funktion false
på argumentet true, og ser ud som følger:
- iszero = S(SI(K(K(SK))))(KK)
Hvordan programmerer man den slags, når
SKI-operationerne virker som ekstremt lavniveau
maskinkode? Det kan faktisk gøres helt systematisk.
Antag, at et SKIX-udtryk E har fået lov til at bruge
et antal parametre x1,...,xk. De
kan elimineres i en induktiv proces, hvor
E omskrives til
[x1],...,[xk]E efter
reglerne:
- [x](E1 E2) =
S
[x]E1
[x]E2,
hvis x forekommer i
E1 eller i
E2
- [x]E =
K E,
hvis x ikke forekommer i
xE
- [x]x = I
Denne algoritme viser designet bag SKI-systemet:
S fordeler en parameter til to undertræer,
K smider en uønsket parameter væk,
og I aflæser en ønsket parameter.
Med denne teknik kan vi fx programmere not, der med
en parameter let kan skrives som:
Med algoritmen kan vi eliminere a og få:
- not = S(SI(K(false)))(K true) = S(SI(K(SK)))(KK)
Kommandoerne translate og constant
understøtter også booleans.
Spørgsmål C
Udvid X.java med funktionen or
på booleans. Den skal skrives med SKI-koder og
derefter skal Java-koden udvides et par steder.
Vi kan nu bygge mere og mere
ovenpå, til vi ril sidst har
et komplet programmeringssprog. Fx kan minus
skrives son (hvorfor?):
Spørgsmål D
Vis, hvordan man tilsvarende kan skrive
funktionerne lt (less-than) og
le (less-than-or-equal).
Det eneste vi nu mangler for at have samme
udtrykskraft som alle andre programmeringssprog er
rekursion, men også det kan lade sig gøre.
Udganhspunktet er en forunderlig operator:
- fix = S(K(S(I)(I)))(S(S(K(S))(K))(K(S(I)(I))))
med egenskaben:
Med denne kan vi i hvert fald lave en uendelig løkke
som fx fix(I) (prøv den!).
Spørgsmål E (frivillig)
Udnyt alt ovenfor til at programmere et SKIX-udtryk, der
beregner fakultetsfunktionen.
Dette spørgsmål er
rigtig vanskeligt, så man får
også denne Challenge godkendt uden at svare
på det. Men det er jo sidste lejlighed til
at imponere på CS Challenge 2016!
BlueJ version:
XBlueJ.zip.
Du deltager i vores Challenge ved senest den 11. december
at sende en e-mail
til mis@cs.au.dk med subject Challenge 12 og
svarene på spørgsmål A, B, C, D og og (eventuelt) E
(i plain text) og
koden til spørgsmål C
i form af et attachment med en ny udgave af
programmet X.java.