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):
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.
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.