Kodutöö 12
Selles praktikumis harjutame lineaarsete tüüpidega arvutamist
Lisalugemine (vabatahtlik):
Idris 2: Quantitative Type Theory in Action peatükid:
- 2: IDRIS 2 AND QUANTITATIVE TYPES
- 3: RESOURCE USAGE PROTOCOLS
Etteantud kood loengust: lineaarne massiiv
import Data.IOArray
import Data.List
namespace Massiivid
%hide Builtin.(#)
%hide Builtin.DPair.(#)
infix 5 #
public export
data L : Type -> Type -> Type where
(#) : (1 _ : a) -> b -> L a b
export
interface Array arr where
write : (1 a : arr) -> Nat -> Double -> arr
read : (1 a : arr) -> Nat -> L arr Double
size : (1 a : arr) -> L arr Nat
withArray : Nat -> ((1 a : arr) -> L arr c) -> c
export
Array (List Double) where
write [] n d = []
write (x :: xs) 0 d = d :: xs
write (x :: xs) (S k) d = x :: write xs k d
read [] n = [] # 0.0
read (x :: xs) 0 = (x::xs) # x
read (x :: xs) (S n) =
let _ # r = read xs n in
x::xs # r
size [] = [] # 0
size (x :: xs) = (x :: xs) # (length (x :: xs))
withArray l f =
let _ # r = f (replicate l 0.0) in
r
export
data LinArray = MkLinArray (IOArray Double)
private
newIOArr : List Double -> IO (IOArray Double)
newIOArr xs =
let l = cast (length xs) in
do a <- newArray l
let upd = zip [0..l-1] xs
traverse_ (uncurry $ writeArray a) upd
pure a
export
Array LinArray where
withArray n f =
unsafePerformIO (do a <- newArray (cast n)
let (_ # r) = f (MkLinArray a)
pure r )
size (MkLinArray a) = MkLinArray a # (cast (max a))
write (MkLinArray a) i v =
unsafePerformIO (do ok <- writeArray a (cast i) v
pure (MkLinArray a))
read (MkLinArray a) i =
unsafePerformIO (do r <- readArray a (cast i)
case r of
Just v => pure (MkLinArray a # v)
Nothing => pure (MkLinArray a # 0))
Ülesanne 1 : implementeeri writeAll
Funktsioonikutse writeAll a xs n kirjutab listi xs elemendid massiivi a alustades indeksist n.
writeAll : Array arr => (1 _ : arr) -> List Double -> Nat -> arr writeAll a xs n = ?writeAll_rhs
testimine:
Main> writeAll [1.0,2.0,3.0] [5.0,6.0,7.0] 0
[5.0, 6.0, 7.0]
Ülesanne 2: massiivi teisendamine listiks
Funktsioonikutse toLst a i j tagastab massiivi a elemendid indeksitega i kuni j listina.
toLst : Array arr => (1 _ : arr) -> Nat -> Nat -> L arr (List Double) toLst a s f = ?toLst_rhs
test:
Main> toLst [1.0,2.0,3.0] 0 3 [1.0, 2.0, 3.0] # [1.0, 2.0, 3.0]
Ülesanne 3: implementeeri massiivis elementide vahetamist
swap : Array arr => (1 _ : arr) -> Nat -> Nat -> arr swap a i j = ?swap_rhs
test:
Main> swap [1.0,2.0,3.0] 0 2 [3.0, 2.0, 1.0]
Etteantud kood: quickSort
-- pseudokood:
-- loop a pivot j hi i =
-- while (j>=hi){
-- if (a[j] < pivot) {
-- swap a[i] a[j]
-- i++
-- }
-- j++
-- }
-- return i
loop: Array arr => (1 a : arr) -> (pivot:Double) -> (j:Nat)
-> (hi:Nat) -> (i:Nat) -> L arr Nat
loop a pivot j hi i =
if j > hi then a # i else
let a # aj = read a j in
if aj < pivot then
let a = Main.swap a i j in
loop a pivot (j+1) hi (i+1)
else
loop a pivot (j+1) hi i
-- pseudokood:
-- partition a lo hi =
-- pivot = a[hi] // pivot on viimane element
-- i = loop a pivot lo (hi-1) lo // tsükkel, kus viimast elementi ei vaata
-- swap a[i] a[hi] // nüüd vahetame viimase elemendi
-- return i // tagastame pivot-i indeksi
-- abiks Nat-i vähenamine
decr : Nat -> Nat
decr 0 = 0
decr (S n) = n
partition : Array arr => (1 a : arr) -> (lo: Nat) -> (hi: Nat) -> L arr Nat
partition a lo hi =
let a # pivot = read a hi
a # i = loop a pivot lo (decr hi) lo
a = Main.swap a i hi
in a # i
-- pseudokood:
-- qs a lo hi =
-- if (lo<hi) {
-- pivot_index = partition a lo hi
-- qs a lo (pivot_indeks - 1)
-- qs a (pivot_indeks + 1) hi
-- }
-- return a
qs : Array arr => (1 a : arr) -> (lo: Nat) -> (hi: Nat) -> arr
qs a lo hi =
if (lo>=hi) then a else
let a # pi = partition a lo hi
a = qs a lo (decr pi)
a = qs a (1 + pi) hi
in a
-- sorteerib kogu massiivi
quickSortArray : Array arr => (1 _ : arr) -> arr
quickSortArray a =
let a # len = size a in
qs a 0 (decr len)
testimine:
Main> quickSortArray [3.0,2.0,1.0,4.0] [1.0, 2.0, 3.0, 4.0]
Ülesanne 4: listi sorteerimine kasutades LinArray-t
quickSortList : List Double -> List Double
quickSortList xs = withArray len f
where len : Nat
len = length xs
f : (1 _ : LinArray) -> L LinArray (List Double)
f a = ?f_rhs
testList : List Double
testList = map cast $ concat [[20,18..0],[1,3..19]]
testimine:
Main> :exec printLn $ quickSortList [3.0,2.0,1.0,4.0] [1.0, 2.0, 3.0, 4.0] Main> :exec printLn $ quickSortList testList [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0]
Ülesanne 5: Tüübituletus
"Joonista" tüübituletuspuu, kirjuta välja kõik kitsendused ja lahenda kogu avaldise tüüp ɣ2.
Lihtsustuseks:
- ei pea kirjutama xᵅ ∈ Γ
- kitsendusi ei pea kirjutama puu sisse (mis oli slaididel roheline)
Ülesanded:
- ⊢ (λxᵅ¹. ((λyᵅ². yᵅ³)ˠ¹ xᵅ⁴)ᵝ¹)ˠ²
- ⊢ (λxᵅ¹. (xᵅ² (λyᵅ³. yᵅ⁴)ˠ¹)ᵝ¹)ˠ²
- ⊢ (λxᵅ¹. ((λyᵅ². (λzᵅ³. yᵅ⁴)ˠ¹)ˠ³ xᵅ⁵)ᵝ¹)ˠ²
- ⊢ (λxᵅ¹. ((λyᵅ². (λzᵅ³. zᵅ⁴)ˠ¹)ˠ³ xᵅ⁵)ᵝ¹)ˠ²