From 777133c94a985539a0226856b606f2a845dcf503 Mon Sep 17 00:00:00 2001 From: Francesco Minnocci Date: Wed, 27 Apr 2022 12:57:33 +0200 Subject: [PATCH] Add lab7 --- lab7/Program.fs | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ ludo/Program.fs | 2 +- 2 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 lab7/Program.fs diff --git a/lab7/Program.fs b/lab7/Program.fs new file mode 100644 index 0000000..d7d4a4c --- /dev/null +++ b/lab7/Program.fs @@ -0,0 +1,99 @@ +type aexp = + AEint of int + | AEplus of (aexp * aexp) + | AEminus of (aexp * aexp) + | AEtimes of (aexp * aexp) + +// funzione di interpretazione +let rec aexp_to_string : aexp -> string = + fun e -> + match e with + AEint i -> sprintf "%d" i + | AEplus (e,f) -> sprintf "(%s + %s)" (aexp_to_string e) (aexp_to_string f) + | AEminus (e,f) -> sprintf "(%s - %s)" (aexp_to_string e) (aexp_to_string f) + | AEtimes (e,f) -> sprintf "(%s * %s)" (aexp_to_string e) (aexp_to_string f) + +(* printfn "%s" (aexp_to_string (AEplus ((AEint 10),(AEint 6)))) *) + +// semantic domain +type eval = int + +// error handling +let negativeError () = failwith "natural numbers should be positive or zero" + +// denotational semantics +let rec sem : aexp -> eval = + fun ae -> + match ae with + AEint i -> + if i < 0 then negativeError () else i + | AEplus (e,f) -> + sem e + sem f + | AEminus (e,f) -> + sem e - sem f + | AEtimes (e,f) -> + sem e * sem f + +(* printfn "%d" (sem (AEplus ((AEint 10),(AEint 6)))) *) + +let eval_to_string : eval -> string = + fun e -> Printf.sprintf "%d" e + +let eval : aexp -> unit = + fun ae -> + printfn "%s ==> " (aexp_to_string ae); + try + printfn "%s\n" (eval_to_string (sem ae)) + with + Failure message -> + printfn "error: %s\n" message + +printfn "%A" (eval (AEplus ((AEint 10),(AEint 6)))) + +// parallel computation +open System.Threading +open System.Threading.Tasks + +// esempio di funzioni parallele +let runTasks () = + let rnd = System.Random() + + for i = 1 to 10 do + let t = new Task(fun () -> + let time = rnd.Next(3000) + Thread.Sleep time + printfn "Thread %d waited for %d milliseconds" i time + ) + t.Start() + +// il risultato non è deterministico +let parallelIncrement () = + let a = [| 0 |] + for i = 1 to 100 do + let t = new Task(fun () -> + Thread.Sleep 100 + a[0] <- a[0] + 1 + printfn "Thread %d done" i + ) + t.Start() + a + +// usiamo lock per fixare il problema della lettura concorrente +// di una cella di memoria da parte di più "thread" +let parIncr2 () = + let rnd = System.Random() + let a = [| 0 |] + + Array.Parallel.iter (fun i -> + lock a (fun () -> + let x = a[0] + Thread.Sleep (rnd.Next 10) + a[0] <- x + 1 + printfn "Thread %d done" i + ) + ) [| 1 .. 1000 |] + a + +printfn "%A" (parIncr2 ()) + +// però, la lock non risolve problemi con più risorse (i.e. dining philosophers problem) diff --git a/ludo/Program.fs b/ludo/Program.fs index 9708eb6..360e254 100644 --- a/ludo/Program.fs +++ b/ludo/Program.fs @@ -36,7 +36,7 @@ let rec sumFirstFun f k = let rec fold g f k1 k2 z = if (k2 < k1) then z else g (fold g f (k1+1) k2 z) (f(k1)) - +> let sum x y = x + y let double x = 2*x