Add lab7
parent
9b544600d8
commit
777133c94a
@ -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)
|
Loading…
Reference in New Issue