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