Gödel-számozás

Használható segédanyagok: Haskell könyvtárainak dokumentációja, (lokális!) Hoogle, a tárgy honlapja és a BE-AD rendszerbe feltöltött beadandók. Ha bármilyen kérdés, észrevétel felmerül, azt a felügyelőknek kell jelezni, NEM a diáktársaknak!

Tekintve, hogy a tesztesetek, bár odafigyelés mellett íródnak, nem fedik le minden esetben a függvény teljes működését, határozattan javasolt még külön próbálgatni a megoldásokat beadás előtt, vagy megkérdezni a felügyelőket!

A feladat összefoglaló leírása

A Gödel-számozás egy leképezés, amely minden kifejezéshez egy számot rendel hozzá, és a híres, Gödel-féle nemteljességi tétel bizonyításához használják, de felfogható kódolásként is. A feladatban egy egyszerűsített Gödel-számozást fogunk megvalósítani.

Szótár megadása (1 pont)

Adjuk meg a leképezéshez használandó szótárat! A szótárnak rendezett párokat kell tartalmaznia, melyben az első elem a karakter a második a hozzá tartozó szám/kód.

type Dictionary = [(Char, Int)]

A szótárt előállító függvény paraméterül kapja, hogy milyen karakterek szerepeljenek a szótárban. A kódok kiosztását 1-től kezdi, növekvő sorrendben. Például:

[('a', 1), ('b', 2), ..., ('z', 26), ('A', 27), ('B', 28)
, ..., ('Z', 52), ('.', 53), ('!', 54)]

A függvény:

dictionary :: [Char] -> Dictionary

Test>
[('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7), ('h', 8), ('i', 9), ('j', 10), ('k', 11), ('l', 12), ('m', 13), ('n', 14), ('o', 15), ('p', 16), ('q', 17), ('r', 18), ('s', 19), ('t', 20), ('u', 21), ('v', 22), ('w', 23), ('x', 24), ('y', 25), ('z', 26), ('A', 27), ('B', 28), ('C', 29), ('D', 30), ('E', 31), ('F', 32), ('G', 33), ('H', 34), ('I', 35), ('J', 36), ('K', 37), ('L', 38), ('M', 39), ('N', 40), ('O', 41), ('P', 42), ('Q', 43), ('R', 44), ('S', 45), ('T', 46), ('U', 47), ('V', 48), ('W', 49), ('X', 50), ('Y', 51), ('Z', 52)] :: Dictionary
Test>
[('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7), ('h', 8), ('i', 9), ('j', 10), ('k', 11), ('l', 12), ('m', 13), ('n', 14), ('o', 15), ('p', 16), ('q', 17), ('r', 18), ('s', 19), ('t', 20), ('u', 21), ('v', 22), ('w', 23), ('x', 24), ('y', 25), ('z', 26), ('A', 27), ('B', 28), ('C', 29), ('D', 30), ('E', 31), ('F', 32), ('G', 33), ('H', 34), ('I', 35), ('J', 36), ('K', 37), ('L', 38), ('M', 39), ('N', 40), ('O', 41), ('P', 42), ('Q', 43), ('R', 44), ('S', 45), ('T', 46), ('U', 47), ('V', 48), ('W', 49), ('X', 50), ('Y', 51), ('Z', 52), ('.', 53), ('!', 54)] :: Dictionary
Test>
[('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7), ('h', 8), ('i', 9), ('j', 10), ('k', 11), ('l', 12), ('m', 13), ('n', 14), ('o', 15), ('p', 16), ('q', 17), ('r', 18), ('s', 19), ('t', 20), ('u', 21), ('v', 22), ('w', 23), ('x', 24), ('y', 25), ('z', 26), ('A', 27), ('B', 28), ('C', 29), ('D', 30), ('E', 31), ('F', 32), ('G', 33), ('H', 34), ('I', 35), ('J', 36), ('K', 37), ('L', 38), ('M', 39), ('N', 40), ('O', 41), ('P', 42), ('Q', 43), ('R', 44), ('S', 45), ('T', 46), ('U', 47), ('V', 48), ('W', 49), ('X', 50), ('Y', 51), ('Z', 52), ('1', 53), ('2', 54), ('3', 55), ('4', 56), ('5', 57), ('6', 58), ('7', 59), ('8', 60), ('9', 61), ('0', 62)] :: Dictionary

Kód meghatározása (1 pont)

Adjuk meg azt a függvényt, amely a megadott szótárban megkeresi a karakterhez rendelt értéket, kódot!

charToNum :: Dictionary -> Char -> Maybe Int

Test>
Just 1 :: Maybe Int
Test>
Nothing :: Maybe Int
Test>
Nothing :: Maybe Int

Szöveg leképezése (2 pont)

Adjuk meg azt a függvényt, amely egy szöveget átalakít a neki megfelelő számsorozattá! Az átalakításhoz használja fel a paraméterül kapott szótárat! Ha a szövegben illegális karakter található, akkor ezeknek az értéke legyen 0.

translate :: Dictionary -> String -> [Int]

Test>
[7, 15, 5, 4, 5, 12] :: [Int]
Test>
[0, 15, 5, 4, 5, 12] :: [Int]
Test>
[0, 0, 0, 0, 0, 0] :: [Int]

Prímek listája (2 pont)

Hogy a szöveghez számértékeket tudjunk rendelni, szükség lesz a prímek végtelen listájára.

primeList :: [Integer]

Test>
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29] :: [Integer]
Test>
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541] :: [Integer]

Gödel-számmá kódolás (3 pont)

Adjuk meg azt a függvényt, amely egy szövegnek megadja a neki megfelelő Gödel-számot! A kódoláshoz szükségünk lesz a szöveghez tartozó számsorozatra és a prímek listájára is.

A kódoláshoz a következő képlet szerint fogunk eljárni:

GoedelNumberingec51044c6535558a2ac6f45f9f28d2a9.png

ahol:

Nézzünk egy konkrét példát:

encode :: Dictionary -> String -> Integer

Test>
3150 :: Integer
Test>
1575 :: Integer
Test>
211392921600 :: Integer
Test>
1 :: Integer

Kódhoz tartozó karakter (2 pont)

Adjuk meg azt a függvényt, amely a megadott szótárban megkeresi a számhoz rendelt karaktert!

numToChar :: Dictionary -> Int -> Maybe Char

Test>
Nothing :: Maybe Char
Test>
Nothing :: Maybe Char
Test>
Just 'P' :: Maybe Char

Prímfaktorizáció (3 pont)

A továbbiakban egy számból elő szeretnénk állítani az eredeti kifejezést. Ehhez adjuk meg azt a függvényt, amely egy pozitív egész számot prímtényezők szorzatára bontja!

primeFactorization :: Integer -> [Integer]

Test>
[] :: [Integer]
Test>
[2, 3, 7] :: [Integer]
Test>
[661] :: [Integer]

Gödel-szám dekódolása (4 pont)

Adjuk meg azt a függvényt, amely egy Gödel-szám és egy szótár segítségével előállítja az eredeti kifejezést! A dekódoláshoz a paraméterül kapott egész értéket prímtényezőkre kell bontani, és az azonos prímek számossága adja meg a kódot, az előállított kódok alapján pedig elő tudjuk állítani az eredeti szöveget. Ha illegális kódot találunk, azaz a szótárban nincs ilyen bejegyzés, akkor azt cseréljük a '*' (csillag) karakterre!

decode :: Dictionary -> Integer -> String

Test>
"bba" :: String
Test>
"bba" :: String
Test>
"*bba" :: String
Test>
"Abba" :: String
Test>
"abba" :: String
Test>
"a" :: String

Pontozás

Ponthatárok: