TEXTÄVENTYRET är skrivet i DPG-PROLOG. Detta är en svensk prologvariant utvecklat för gymnasieskolan. Alla predikaten är på svenska. Variabler börjar med liten bokstav, istället för med stor. Alla inbygda predikat (med speciell innebörd) har alla bokstäver versala.

Vad jag förstår har jag brutit mot konventionen i hur man konstruerar predikaten. Jag kan inte dessa regler, men har för mig att jag har kastat om ordningen på attributen till de tvåställiga predikaten. (Fast detta är bara en konvention och har inget med språkets funktionalitet att göra.)

För varje fråga som ställs till databasen, går exekveraren igenom all data och alla regler från början till slut. Så fort den hittar en överensstämmelse retuneras Sant och den försöker inte finna några flera överensstämmelser. Detta gäller även för regler med och och eller. Är vänstra ledet i en och sats falsk, retuneras falskt och exekveraren kontrollerar aldrig högra ledet. På motsvarande vis exekveras inte högra ledet i en eller-sats om det vänstra ledet är sant. Detta är mycket viktigt att känna till eftersom man mitt i reglerna kan lägga in händelser, såsom förändringar av regler och utskrifter på skärmen. Om exekveraren inte prövar dessa satser, sker inte händelsen.

När variabler påträffas provar exekveraren genom att sätta in alla de värden som förekommer i det predikatet, tills uttrycket blir sant.

Motsvarigheten för
For i=1 to 10; print i; next;
blir i prolog
Räkna(i) <- SKRIV(i) & SKRIV(', ' & (i=10 ELLER Räkna(i+1)).
Vi startar rekursionen genom att ange:
Räkna(1).
Datorn svarar med:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, Ja.

Här är en förklaring på den inbyggda predikat jag använt (och dess ställighet):

SKRIV 1
Skriver ut en sak.
NR 0
Skriver en ny rad.
TAGBORT 1
Raderar en sak ur basen.
LÄGGTILL 1
Lägger till en sak i basen.
FALSK 0
Är alltid falsk. Exekveraren prövar nästa alternativ.

Och här kommer TEXTÄVENTYRET

Plats(Stig).
Plats(Träd).
Plats(Buskar).
Plats(Trädkrona).
Plats(Ingång).
Plats(Hål).
Plats(Fågelbo).
Plats(Galler).
Plats(Stor_korsning).
Plats(Tvåhandtagsdörr).
Plats(Stockdörr).
Plats(Slibbrum).
Plats(Lagerförråd).
Plats(Vapenförråd).
Plats(Bred_gång).
Plats(Broända).

N(Stig, Ingång).
NÖ(Stig, Buskar).
SÖ(Ingång, Buskar).
Ö(Träd, Stig).
Ö(Tvåhandtagsdörr, Stor_korsning).
In(Ingång, Galler <- Läge(Port, Öppen).
Utsikt(NV, Trädkrona, Ingång).
Sett_något(Inget).

Plats(Port, Ingång).
Plats(Spade, Buskar).
Plats(Stor_nyckel, Hål).
Plats(Fågelbo, Trädkrona).
Plats(Ägg, Fågelbo).
Plats(Läkande_dryck, Ryggsäck).
Plats(Styrkedryck, Ryggsäck).
Plats(Flygdryck, Ryggsäck).
Plats(Osynlighetsdryck, Ryggsäck).
Plats(Frätande_vätska, Ryggsäck).
Plats(Sömndryck, Ryggsäck).
Plats(Sanningsdryck, Ryggsäck).
Plats(Antimagidryck, Ryggsäck).
Plats(Explotionsvätska, Ryggsäck).
Plats(Ryggsäck, Rygg).
Plats(Tvåhandtagsdörr, Tvåhandtagsdörr).
Plats(Rygg, här) <- Här(här).
Plats(Hand, här) <- Här(här).

Läge(Port, Låst).
Läge(Port, Stängd).
Läge(Port, Stängbar).
Läge(Spade, Medtagbar).
Läge(Stor_nyckel, Medtagbar).
Läge(Hål, Ogrävd).
Läge(Ägg, Medtagbar).
Läge(Fågelbo, Öppen).
Läge(Rygg, Öppen).
Läge(Ryggsäck, Stängd).
Läge(Läkande_dryck, Medtagbar).
Läge(Styrkedryck, Medtagbar).
Läge(Flygdryck, Medtagbar).
Läge(Osynlighetsdryck, Medtagbar).
Läge(Frätande_vätska, Medtagbar).
Läge(Sömndryck, Medtagbar).
Läge(Antimagidryck, Medtagbar).
Läge(Explotionsvätska, Medtagbar).
Läge(Ryggsäck, Medtagbar).
Läge(Ryggsäck, Stängbar).
Läge(Tvåhandtagsdörr, Stängd).

Dörr(Port).
Dörr(Tvåhandtagsdörr).

Nyckel(Stor_nyckel).

Passar(Port, Stor_nyckel).

Föremålsbeskrivning(Ägg) <-
    Läge(Ägg, Tappat) &
    SKRIV('Ägget är kläckt!') & NR &
    FALSK.
Föremålsbeskrivning(föremål) <-
    Läge(föremål, Öppen) &
    SKRIV(föremål) &
    SKRIV(' är öppen.') & NR.
Föremålsbeskrivning(föremål) <-
    Läge(föremål, Stängd) &
    SKRIV(föremål) &
    SKRIV(' är stängd.') & NR.
Föremålsbeskrivning(föremål).

S(plats1, plats2) <- N(plats2, plats1) & plats1 /= plats2.
V(plats1, plats2) <- Ö(plats2, plats1) & plats1 /= plats2.
NV(plats1, plats2) <- SÖ(plats2, plats1) & plats1 /= plats2.
SV(plats1, plats2) <- NÖ(plats2, plats1) & plats1 /= plats2.
Ner(plats1, plats2) <- Upp(plats2, plats1) & plats1 /= plats2.
Ut(plats1, plats2) <- In(plats2, plats1) & plats1 /= plats2.

Läge(föremål, Öppningsbar) <- Läge(föremål, Stängbar).

Riktning(N).
Riktning(S).
Riktning(Ö).
Riktning(V).

Riktning(NÖ).
Riktning(SV).
Riktning(SÖ).
Riktning(NV).

Riktning(Upp).
Riktning(Ner).
Riktning(In).
Riktning(Ut).


Här(Stig).

Gå(riktning) <-
    Här(plats) &
    Riktning(riktning) &
    Plats(ny_plats) &
    plats /= ny_plats &
    riktning(plats, ny_plats) &
    SKRIV('Du gick: ') &
    SKRIV(riktning) & NR &
    Teleport(ny_plats).
Gå(ny_plats) <-
    Här(plats) &
    Plats(ny_plats) &
    Riktning(riktning) &
    riktning(plats, ny_plats) &
    SKRIV('Du gick till: ') &
    SKRIV(ny_plats) & NR &
    Teleport(ny_plats).

Teleport(ny_plats) <-
    TAGBORT(Här(plats)) &
    LÄGGTILL(Här(ny_plats)) &
    Platsbeskrivning(ny_plats) & NR.

Platsbeskrivning(plats) <-
    SKRIV('Du befinner dig nu vid:') & NR &
    SKRIV(plats) & NR & NR &
    SKRIV('Du ser: ') &
    Innehållsbeskrivning(plats) & NR &
    Innutibeskrivning(plats) & NR &
    Utgångsbeskrivning(plats) & NR &
    Utsiktsbeskrivning(plats).

Utgångsbeskrivning(plats) <-
    SKRIV('Du kan gå:') & NR &
    Riktning(riktning) &
    Plats(ny_plats) &
    riktning(plats, ny_plats) &
    SKRIV(riktning) &
    SKRIV(' till ') &
    SKRIV(ny_plats) & NR &
    FALSK.
Utgångsbeskrivning(plats).

Se <- Här(plats) & Platsbeskrivning(plats) & NR.
Se(föremål) <-
    Här(här) &
    (
        Plats(föremål, här)
    ELLER
        Plats(föremål, Hand)
    ) &
    Föremålsbeskrivning(föremål) & NR &
    SKRIV('Du ser: ') &
    Innehållsbeskrivning(föremål) & NR.

Klättra(riktning) <-
    (riktning = Upp ELLER riktning = Ner) &
    Gå(riktning).
Klättra(riktning) <-
    (ICKE(riktning = Upp) ELLER ICKE(riktning = Ner)) &
    SKRIV('Du kan bara klättra upp eller ner.') & NR.

Smyg(någonstans) <- Gå(någonstans).

Utsiktsbeskrivning(plats) <-
    Utsikt(riktning, plats, utsikt) &
    SKRIV('Åt ') &
    SKRIV(riktning) &
    SKRIV(' ser du ') &
    SKRIV(utsikt) &
    SKRIV('.') & NR &
    FALSK.
Utsiktsbeskrivning(plats).

Ta(föremål) <-
    Här(här) &
    (
        Plats(föremål, här)
    ELLER
        Plats(föremål, föremål_2) &
        Plats(föremål_2, här) &
        Läge(föremål_2, Öppen)
    ) &
    Läge(föremål, Medtagbar) &
    (
        TAGBORT(Plats(föremål, här))
    ELLER
        TAGBORT(Plats(föremål, föremål_2))
    ) &
    LÄGGTILL(Plats(föremål, Hand)) &
    SKRIV('OK') & NR.
Ta(föremål) <-
    Här(här) &
    ICKE(Plats(föremål, här)) &
    SKRIV('Du ser inte ') &
    SKRIV(föremål) &
    SKRIV(' här.') & NR.
Ta(föremål) <-
    Plats(föremål, Hand) &
    SKRIV('Du har redan ' &
    SKRIV(föremål) &
    SKRIV(' i handen.') & NR.

Lämna(föremål) <-
    Här(här) &
    Plats(föremål, Hand) &
    Läge(föremål, Medtagbar) &
    TAGBORT(Plats(föremål, Hand)) &
    LÄGGTILL(Plats(föremål, här)) &
    SKRIV('OK') & NR &
    FALSK.
Lämna(föremål_1, föremål_2) <-
    Här(här) &
    Plats(föremål_2, här) &
    (
        Plats(föremål_1, här)
    ELLER
        Plats(föremål_1, föremål_3) &
        Plats(föremål_3, här) &
        Läge(föremål_3, Öppen)
    ) &
    Läge(föremål_1, Medtagbar) &
    Läge(föremål_2, Öppen) &
    (
        TAGBORT(Plats(föremål_1, här))
    ELLER
        TAGBORT(Plats(föremål_1, föremål_3))
    ) &
    LÄGGTILL(Plats(föremål_1, föremål_2)) &
    SKRIV('OK') & NR.
Sätt(föremål_1, föremål_2) <- Lämna(föremål_1, föremål_2).
Placera(föremål_1, föremål2) <- Lämna(föremål_1, föremål_2).
Flytta(föremål_1, föremål2) <- Lämna(föremål_1, föremål_2).

Släpp(Ägg) <-
    Plats(Ägg, Hand) &
    LÄGGTILL(Läge(Ägg, Kläckt)) &
    LÄGGTILL(Läge(Ägg, Tappat)) &
    SKRIV('Ägget faller ocj kläcks!') & NR &
    Lämna(Ägg) &
    TAGBORT(Läge(Ägg, Medtagbar)).
Släpp(föremål) <- Lämna(föremål).
Kasta(föremål) <- Släpp(föremål).
Släng(föremål) <- Släpp(föremål).
Lämna(föremål).

Innehållsbeskrivning(plats) <-
    (
        Plats(plats)
    ELLER
        Läge(plats, Öppen)
    ) &
    Plats(föremål, plats) &
    föremål /= Hand &
    föremål /= Rygg &
    SKRIV(föremål) & NR &
    TAGBORT(Sett_något(Inget) &
    LÄGGTILL(Sett_något(!)) &
    FALSK.
Innehållsbeskrivning(plats) <-
    Sett_något(avslutning) &
    SKRIV(avslutning) & NR &
    TAGBORT(Sett_något(avslutning)) &
    LÄGGTILL(Sett_något(Inget)).

Innutibeskrivning(plats) <-
    Här(här) &
    föremål_1 /= Hand &
    föremål_1 /= Rygg &
    Plast(föremål_1, här) &
    Läge(föremål_1, Öppen) &
    Plats(föremål_2, föremål_1) &
    SKRIV('I ') &
    SKRIV(föremål_1) &
    SKRIV(' ser du ') &
    SKRIV(föremål_2) &
    SKRIV('.') & NR &
    FALSK.
Innutibeskrivning(plats).

Öppna(föremål) <-
    ICKE(Läge(föremål, Låst)) &
    Här(här) &
    Plats(föremål, här) &
    Läge(föremål, Stängd) &
    Läge(föremål, Öppningsbar) &
    TAGBORT(Läge(föremål, Stängd)) &
    LÄGGTILL(Läge(föremål, Öppen)) &
    SKRIV('OK') & NR.

Stäng(föremål) <-
    Här(här) &
    Läge(föremål, Öppen) &
    (
        Plats(föremål, här)
    ELLER
        Plats(föremål, Hand)
    ) &
    TAGBORT(Läge(föremål, Öppen)) &
    LÄGGTILL(Läge(förmål, Stängd)) &
    SKRIV('OK') & NR.

Inventarier<-
    SKRIV('I händerna ser du:') & NR &
    Innehållsbeskrivning(Hand) & NR &
    SKRIV('Och på ryggen hänger') & NR &
    Innehållsbeskrivning(Rygg) & NR.
I <- Inventarier.

Lås_upp(sak) <-
    Här(här) &
    Läge(sak, Låst) &
    Plats(sak, här) &
    Passar(sak, nyckel) &
    Plats(nyckel, Hand) &
    TAGBORT(Läge(sak, Låst)) &
    SKRIV('OK') & NR.

Gräv <-
    Plats(Spade, Hand) &
    Här(Ingång) &
    Läge(Hål, Ogrävd) &
    LÄGGTILL(Upp(Hål, Ingång)) &
    TAGBORT(Läge(Hål, Ogrävd)) &
    LÄGGTILL(Läge(Hål, Grävd)) &
    SKRIV('OK') & NR.
Gräv <-
    Plats(Spade, plats) &
    plats /= Hand &
    SKRIV('Du bär ingen spade.') & NR.
Gräv <-
    Plats(Spade, Hand) &
    Här(plats) &
    plats /= Ingång &
    SKRIV('Du hittar inget av intresse,') & NR &
    SKRIV('inget bra ställe att gräva på.') & NR.

Öppna(Tvåhandtagsdörr) <-
    SKRIV('Lägg till vilken av de två handtagen du väljer.') & NR.
Öppna(Tvåhandtagsdörr, höger) <-
    Läge(Tvåhandtagsdörr, Stängd) &
    TAGBORT(Läge(Tvåhandtagsdörr, Stängd)) &
    LÄGGTILL(Läge(Tvåhandtagsdörr, Öppen)) &
    SKRIV('OK') & NR.

Kommentarer

Det finns mycket som skulle kunna göras bättre. Exempelvis kan man baka in felmeddelandena tillsammans med kontrollerna innan händelserna utförs. Föremålen skulle kunna ha koder istället för raka namn, så att flera föremål kan ha samma kallelsenamn. Man skulle kunna baka in flera attribut till fölremålen på en och samma rad. De skulle kunna ha vikt, etc.

Det skulle vara kul att göra något nytt, lite bättre, och mera fullständigt. Äventyret ovan har bara ett fåtal rum.