Adding tests, adding miniFun implementation

This commit is contained in:
elvis
2024-10-20 20:28:44 +02:00
parent de2e8bbd86
commit 8b274ebda4
8 changed files with 759 additions and 222 deletions

View File

@ -1,222 +1 @@
open Lang.MiniImp print_endline "Hello!"
(* -------------------------------------------------------------------------- *)
(* Identity program *)
let program =
Main
("a",
"b",
(Assignment ("b", (Variable "a")))
)
;;
Printf.printf "%d\n" (reduce 1 program)
(* -------------------------------------------------------------------------- *)
(* y not defined program *)
let program =
Main
("a",
"b",
(Sequence (
(Assignment ("x", (Integer 1))),
(Assignment ("b",
(Plus ((Plus (Variable "a", Variable "x")), (Variable "y")))))
)
)
)
;;
try
Printf.printf "%d\n" (reduce 100 program)
with AbsentAssignment s ->
Printf.printf "%s\n" s
;;
(* -------------------------------------------------------------------------- *)
(* factorial program *)
let program =
Main
("a",
"b",
(Sequence (
(Assignment ("b", (Integer 1))),
(For (
(Assignment ("i", (Integer 1))),
(BCmpLessEq (Variable "i", Variable "a")),
(Assignment ("i", (Plus ((Variable "i"), (Integer 1))))),
(Assignment ("b", (Times (Variable "b", Variable "i"))))
)
)
)
)
)
;;
Printf.printf "%d\n" (reduce 10 program)
;;
(* -------------------------------------------------------------------------- *)
(* hailstone sequence's lenght program *)
let program =
Main
("a",
"b",
(Sequence (
(Assignment ("b", (Integer 1))),
(While (
(BNot (BCmp ((Variable "a"), (Integer 1)))),
(Sequence (
(Assignment ("b", (Plus (Variable "b", Integer 1)))),
(If (
(BCmp (Modulo (Variable "a", Integer 2), Integer 1)),
(Assignment ("a", Plus (Times (Integer 3, Variable "a"), Integer 1))),
(Assignment ("a", Division (Variable "a", Integer 2)))
))
))
))
))
)
;;
Printf.printf "%d\n" (reduce 77031 program)
;;
(* -------------------------------------------------------------------------- *)
(* sum multiples of 3 and 5 program *)
let program =
Main
("a",
"b",
(Sequence (
(Assignment ("b", (Integer 0))),
(For (
(Assignment ("i", Integer 0)),
(BCmpLess (Variable "i", Variable "a")),
(Assignment ("i", Plus (Variable "i", Integer 1))),
(If (
(BOr ((BCmp (Modulo (Variable "i", Integer 3), Integer 0)),
(BCmp (Modulo (Variable "i", Integer 5), Integer 0)))),
(Assignment ("b", Plus (Variable "b", Variable "i"))),
(Skip)
))
))
))
)
;;
Printf.printf "%d\n" (reduce 12345 program)
;;
(* -------------------------------------------------------------------------- *)
(* rand program *)
let program =
Main
("a",
"b",
(Assignment ("b", Rand (Variable "a")))
)
;;
Printf.printf "%d\n" (reduce 10 program)
;;
(* -------------------------------------------------------------------------- *)
(* fibonacci program *)
let program =
Main
("n",
"fnext",
(Sequence (
Sequence (
(Assignment ("fnow", Integer 0)),
(Assignment ("fnext", Integer 1))
),
(While (
(BCmpGreater (Variable "n", Integer 1)),
(Sequence (
(Sequence (
(Assignment ("tmp", Plus (Variable "fnow", Variable "fnext"))),
(Assignment ("fnow", Variable "fnext"))
)),
(Sequence (
(Assignment ("fnext", Variable "tmp")),
(Assignment ("n", Minus (Variable "n", Integer 1)))
))
))))
))
)
;;
Printf.printf "%d\n" (reduce 48 program)
;;
(* -------------------------------------------------------------------------- *)
(* Miller-Rabin primality test program *)
let program =
Main
("n",
"result",
Sequence (
(Assignment ("result", Integer 0)),
(Sequence (
(Sequence (
(Assignment ("s", Integer 0)),
(While (
(BCmp (Integer 0,
Modulo (
Division (
(Minus (Variable "n", Integer 1)),
(Power (Integer 2, Variable "s"))),
(Integer 2)
)
)
),
(Assignment ("s", Plus (Variable "s", Integer 1)))
))
)),
(Sequence (
(Assignment ("d", Division (Minus (Variable "n", Integer 1), Power (Integer 2, Variable "s")))),
(For (
(Assignment ("i", Integer 20)),
(BCmpGreater (Variable "i", Integer 0)),
(Assignment ("i", Minus (Variable "i", Integer 1))),
(Sequence (
Sequence (
(Assignment ("a", Plus (Rand (Minus (Variable "n", Integer 4)), Integer 2))),
(Assignment ("x", PowerMod (Variable "a", Variable "d", Variable "n")))),
Sequence (
(For (
(Assignment ("j", Integer 0)),
(BCmpLess (Variable "j", Variable "s")),
(Assignment ("j", Plus (Variable "j", Integer 1))),
(Sequence (
Sequence (
(Assignment ("y", PowerMod (Variable "x", Integer 2, Variable "n"))),
(If (
(BAnd (BAnd (BCmp (Variable "y", Integer 1), BNot (BCmp (Variable "x", Integer 1))), BNot (BCmp (Variable "x", Minus (Variable "n", Integer 1))))),
(Assignment ("result", Integer 1)),
(Skip)
))),
(Assignment ("x", Variable "y"))
))
)),
(If (
(BNot (BCmp (Variable "y", Integer 1))),
(Assignment ("result", Integer 1)),
(Skip)
)))
))
))
))
))
)
)
;;
(* should return 0 because prime *)
Printf.printf "%d\n" (reduce 179424673 program)
;;
(* sould return 1 because not prime *)
Printf.printf "%d\n" (reduce 179424675 program)
;;

358
lib/miniFun.ml Normal file
View File

@ -0,0 +1,358 @@
type variable = string
module VariableMap = Map.Make(String)
type t_exp =
Integer of int
| Boolean of bool
| Variable of variable
| Function of variable list * t_exp
| Application of t_exp * t_exp list
| Plus of t_exp * t_exp
| Minus of t_exp * t_exp
| Times of t_exp * t_exp
| Division of t_exp * t_exp
| Modulo of t_exp * t_exp
| Power of t_exp * t_exp
| PowerMod of t_exp * t_exp * t_exp
| Rand of t_exp
| BAnd of t_exp * t_exp
| BOr of t_exp * t_exp
| BNot of t_exp
| Cmp of t_exp * t_exp
| CmpLess of t_exp * t_exp
| CmpLessEq of t_exp * t_exp
| CmpGreater of t_exp * t_exp
| CmpGreaterEq of t_exp * t_exp
| IfThenElse of t_exp * t_exp * t_exp
| LetIn of variable * t_exp * t_exp
| LetFun of variable * variable list * t_exp * t_exp
type permittedValues =
IntegerPermitted of int
| BooleanPermitted of bool
| FunctionPermitted of closure
and closure = {
inputList: variable list;
body: t_exp;
assignments: permittedValues VariableMap.t;
recursiveness: variable option
}
type memory = {
assignments: permittedValues VariableMap.t
}
exception AbsentAssignment of string
exception WrongType of string
exception DivisionByZero of string
exception WrongAriety of string
module Utility = Utility;;
Random.self_init ()
let rec evaluate (mem: memory) (command: t_exp) =
match command with
Integer n -> (IntegerPermitted n)
| Boolean b -> (BooleanPermitted b)
| Variable v -> (
match VariableMap.find_opt v mem.assignments with
None -> raise (AbsentAssignment ("The variable " ^
v ^
" is not defined."))
| Some a -> a
)
| Function (xs, f) ->
(FunctionPermitted
{inputList = xs;
body = f;
assignments = mem.assignments;
recursiveness = None}
)
| Application (f, xs) -> (
let funcClosure = (
match (evaluate mem f) with
FunctionPermitted ff -> ff
| IntegerPermitted _ -> raise (WrongType ("Function is not a function, it's an integer"))
| BooleanPermitted _ -> raise (WrongType ("Function is not a function, it's a boolean"))
) in
let parmList = List.map (fun k -> evaluate mem k) xs in
let rec helper m params values =
match (params, values) with
(_, []) -> (m, params)
| ([], _) ->
raise (WrongAriety ("Function application has arity " ^
(List.length funcClosure.inputList
|> string_of_int) ^
", but was applied to " ^
(List.length xs |> string_of_int) ^
" parameters"))
| (p::tlparams, v::tlvalues) -> helper
(VariableMap.add p v m)
tlparams
tlvalues
in
let (mem2assignments, params) = helper
funcClosure.assignments
funcClosure.inputList
parmList
in (* helper funcClosure or helper mem ??? *)
let mem2 = (
match funcClosure.recursiveness with
None -> {assignments = mem2assignments}
| Some nameF -> {
assignments =
VariableMap.add
nameF
(FunctionPermitted funcClosure)
mem2assignments
}
) in
match params with
[] -> evaluate mem2 funcClosure.body
| _ -> (
FunctionPermitted {funcClosure with inputList = params;
assignments = mem2assignments})
)
| Plus (a, b) ->
let aval = (
match evaluate mem a with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
let bval = (
match evaluate mem b with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
(IntegerPermitted (aval + bval))
| Minus (a, b) ->
let aval = (
match evaluate mem a with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
let bval = (
match evaluate mem b with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
(IntegerPermitted (aval - bval))
| Times (a, b) ->
let aval = (
match evaluate mem a with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
let bval = (
match evaluate mem b with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
(IntegerPermitted (aval * bval))
| Division (a, b) ->
let aval = (
match evaluate mem a with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
let bval = (
match evaluate mem b with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in (
try
(IntegerPermitted (aval / bval))
with Division_by_zero -> raise (DivisionByZero "Dividing by zero")
)
| Modulo (a, b) ->
let aval = (
match evaluate mem a with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
let bval = (
match evaluate mem b with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
(IntegerPermitted (aval mod bval))
| Power (a, b) ->
let aval = (
match evaluate mem a with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
let bval = (
match evaluate mem b with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
(IntegerPermitted (Utility.pow aval bval))
| PowerMod (a, b, c) ->
let aval = (
match evaluate mem a with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
let bval = (
match evaluate mem b with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
let cval = (
match evaluate mem c with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
(IntegerPermitted (Utility.powmod aval bval cval))
| Rand (a) ->
let aval = (
match evaluate mem a with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
)
in
IntegerPermitted (Random.int aval)
| BAnd (a, b) ->
let aval = (
match evaluate mem a with
BooleanPermitted x -> x
| _ -> raise (WrongType ("Value is not an boolean"))
)
in
let bval = (
match evaluate mem b with
BooleanPermitted x -> x
| _ -> raise (WrongType ("Value is not an boolean"))
)
in
(BooleanPermitted (aval && bval))
| BOr (a, b) ->
let aval = (
match evaluate mem a with
BooleanPermitted x -> x
| _ -> raise (WrongType ("Value is not an boolean"))
)
in
let bval = (
match evaluate mem b with
BooleanPermitted x -> x
| _ -> raise (WrongType ("Value is not an boolean"))
)
in
(BooleanPermitted (aval || bval))
| BNot a ->
let aval = (
match evaluate mem a with
BooleanPermitted x -> x
| _ -> raise (WrongType ("Value is not an boolean"))
)
in
(BooleanPermitted (not aval))
| Cmp (exp_1, exp_2) -> (
let exp_1val = match evaluate mem exp_1 with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
in
let exp_2val = match evaluate mem exp_2 with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
in
BooleanPermitted (exp_1val = exp_2val)
)
| CmpLess (exp_1, exp_2) -> (
let exp_1val = match evaluate mem exp_1 with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
in
let exp_2val = match evaluate mem exp_2 with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
in
BooleanPermitted (exp_1val < exp_2val)
)
| CmpLessEq (exp_1, exp_2) -> (
let exp_1val = match evaluate mem exp_1 with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
in
let exp_2val = match evaluate mem exp_2 with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
in
BooleanPermitted (exp_1val <= exp_2val)
)
| CmpGreater (exp_1, exp_2) -> (
let exp_1val = match evaluate mem exp_1 with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
in
let exp_2val = match evaluate mem exp_2 with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
in
BooleanPermitted (exp_1val > exp_2val)
)
| CmpGreaterEq (exp_1, exp_2) -> (
let exp_1val = match evaluate mem exp_1 with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
in
let exp_2val = match evaluate mem exp_2 with
IntegerPermitted x -> x
| _ -> raise (WrongType ("Value is not an integer"))
in
BooleanPermitted (exp_1val >= exp_2val)
)
| IfThenElse (guard, if_exp, else_exp) ->
let bguard = (
match evaluate mem guard with
BooleanPermitted b -> b
| _ -> raise (WrongType ("Value in if guard is not a boolean"))
) in
if bguard then
evaluate mem if_exp
else
evaluate mem else_exp
| LetIn (x, xval, rest) ->
let evalxval = evaluate mem xval in
let mem2 = {assignments = VariableMap.add x evalxval mem.assignments} in
evaluate mem2 rest
| LetFun (f, xs, fbody, rest) ->
let mem2 = {
assignments =
VariableMap.add
f
(FunctionPermitted
{ inputList = xs;
body = fbody;
assignments = mem.assignments;
recursiveness = Some f})
mem.assignments}
in
evaluate mem2 rest
let reduce (program: t_exp) (iin : int) =
let program' = (Application (program, [(Integer iin)])) in
let mem : memory = {assignments = VariableMap.empty} in
match (evaluate mem program') with
IntegerPermitted a -> a
| _ -> raise (WrongType ("Main function doesn't return an integer"))

51
lib/miniFun.mli Normal file
View File

@ -0,0 +1,51 @@
type variable = string
module VariableMap : Map.S with type key = variable
type t_exp =
Integer of int
| Boolean of bool
| Variable of variable
| Function of variable list * t_exp
| Application of t_exp * t_exp list
| Plus of t_exp * t_exp
| Minus of t_exp * t_exp
| Times of t_exp * t_exp
| Division of t_exp * t_exp
| Modulo of t_exp * t_exp
| Power of t_exp * t_exp
| PowerMod of t_exp * t_exp * t_exp
| Rand of t_exp
| BAnd of t_exp * t_exp
| BOr of t_exp * t_exp
| BNot of t_exp
| Cmp of t_exp * t_exp
| CmpLess of t_exp * t_exp
| CmpLessEq of t_exp * t_exp
| CmpGreater of t_exp * t_exp
| CmpGreaterEq of t_exp * t_exp
| IfThenElse of t_exp * t_exp * t_exp
| LetIn of variable * t_exp * t_exp
| LetFun of variable * variable list * t_exp * t_exp
type permittedValues =
IntegerPermitted of int
| BooleanPermitted of bool
| FunctionPermitted of closure
and closure = {
inputList: variable list;
body: t_exp;
assignments: permittedValues VariableMap.t;
recursiveness: variable option
}
type memory = {
assignments: permittedValues VariableMap.t
}
exception AbsentAssignment of string
exception WrongType of string
exception DivisionByZero of string
exception WrongAriety of string
val reduce : t_exp -> int -> int

View File

@ -1,3 +1,7 @@
(test (test
(name testingImp) (name testingImp)
(libraries lang)) (libraries lang))
(test
(name testingFun)
(libraries lang))

7
test/testingFun.expected Normal file
View File

@ -0,0 +1,7 @@
1
1
5
6
4
-4
55

107
test/testingFun.ml Normal file
View File

@ -0,0 +1,107 @@
open Lang.MiniFun
(* -------------------------------------------------------------------------- *)
(* Identity program *)
let program =
Function
(["a"],
(Variable "a")
)
;;
Printf.printf "%d\n" (reduce program 1)
(* -------------------------------------------------------------------------- *)
(* Constant program *)
let program =
Function
(["a"],
(Integer 1)
)
;;
Printf.printf "%d\n" (reduce program 10)
(* -------------------------------------------------------------------------- *)
(* Partial application of function program *)
let program =
LetIn
("f",
(Function (["x"; "y"], Plus (Variable "x", Variable "y"))),
(Application (Variable "f", [Integer 3]))
)
;;
Printf.printf "%d\n" (reduce program 2)
(* -------------------------------------------------------------------------- *)
(* Partial application of function program *)
let program =
LetFun
("f",
["x"],
(Function (["y"], Plus (Variable "x", Variable "y"))),
(Application (Variable "f", [Integer 3]))
)
;;
Printf.printf "%d\n" (reduce program 3)
(* -------------------------------------------------------------------------- *)
(* Passing functions to functions program *)
let program =
LetIn
("f",
(Function (
["z"],
(Function (
["y"],
Function (
["x"],
(IfThenElse (
CmpLess (Variable "x", Integer 0),
(Application (Variable "y", [Variable "x"])),
(Application (Variable "z", [Variable "x"]))
)))
))
)),
(Application
(
(Application
(Variable "f",
[Function (["x"], Plus (Variable "x", Integer 1))]
)
),
[Function (["x"], Minus (Variable "x", Integer 1))]
)
)
)
;;
Printf.printf "%d\n" (reduce program (3));
Printf.printf "%d\n" (reduce program (-3))
(* -------------------------------------------------------------------------- *)
(* Recursive function program *)
let program =
LetFun
("f",
["x"],
(IfThenElse (CmpLess (Variable "x", Integer 2),Integer 1, Plus (Variable "x", Application (Variable "f", [Minus (Variable "x", Integer 1)])))),
(Variable "f")
)
;;
Printf.printf "%d\n" (reduce program 10)
(* -------------------------------------------------------------------------- *)
(* Scope program *)
let program =
LetIn
("f",
(LetIn ("a", Integer 1, (Function (["y"], Plus (Variable "y", Variable "a"))))),
(LetIn ("a", Integer 2, Variable "f"))
)
;;
Printf.printf "%d\n" (reduce program 4)

9
test/testingImp.expected Normal file
View File

@ -0,0 +1,9 @@
1
The variable y is not defined.
3628800
351
35553600
true
4807526976
0
1

222
test/testingImp.ml Normal file
View File

@ -0,0 +1,222 @@
open Lang.MiniImp
(* -------------------------------------------------------------------------- *)
(* Identity program *)
let program =
Main
("a",
"b",
(Assignment ("b", (Variable "a")))
)
;;
Printf.printf "%d\n" (reduce 1 program)
(* -------------------------------------------------------------------------- *)
(* y not defined program *)
let program =
Main
("a",
"b",
(Sequence (
(Assignment ("x", (Integer 1))),
(Assignment ("b",
(Plus ((Plus (Variable "a", Variable "x")), (Variable "y")))))
)
)
)
;;
try
Printf.printf "%d\n" (reduce 100 program)
with AbsentAssignment s ->
Printf.printf "%s\n" s
;;
(* -------------------------------------------------------------------------- *)
(* factorial program *)
let program =
Main
("a",
"b",
(Sequence (
(Assignment ("b", (Integer 1))),
(For (
(Assignment ("i", (Integer 1))),
(BCmpLessEq (Variable "i", Variable "a")),
(Assignment ("i", (Plus ((Variable "i"), (Integer 1))))),
(Assignment ("b", (Times (Variable "b", Variable "i"))))
)
)
)
)
)
;;
Printf.printf "%d\n" (reduce 10 program)
;;
(* -------------------------------------------------------------------------- *)
(* hailstone sequence's lenght program *)
let program =
Main
("a",
"b",
(Sequence (
(Assignment ("b", (Integer 1))),
(While (
(BNot (BCmp ((Variable "a"), (Integer 1)))),
(Sequence (
(Assignment ("b", (Plus (Variable "b", Integer 1)))),
(If (
(BCmp (Modulo (Variable "a", Integer 2), Integer 1)),
(Assignment ("a", Plus (Times (Integer 3, Variable "a"), Integer 1))),
(Assignment ("a", Division (Variable "a", Integer 2)))
))
))
))
))
)
;;
Printf.printf "%d\n" (reduce 77031 program)
;;
(* -------------------------------------------------------------------------- *)
(* sum multiples of 3 and 5 program *)
let program =
Main
("a",
"b",
(Sequence (
(Assignment ("b", (Integer 0))),
(For (
(Assignment ("i", Integer 0)),
(BCmpLess (Variable "i", Variable "a")),
(Assignment ("i", Plus (Variable "i", Integer 1))),
(If (
(BOr ((BCmp (Modulo (Variable "i", Integer 3), Integer 0)),
(BCmp (Modulo (Variable "i", Integer 5), Integer 0)))),
(Assignment ("b", Plus (Variable "b", Variable "i"))),
(Skip)
))
))
))
)
;;
Printf.printf "%d\n" (reduce 12345 program)
;;
(* -------------------------------------------------------------------------- *)
(* rand program *)
let program =
Main
("a",
"b",
(Assignment ("b", Rand (Variable "a")))
)
;;
Printf.printf "%b\n" ((reduce 10 program) < 10)
;;
(* -------------------------------------------------------------------------- *)
(* fibonacci program *)
let program =
Main
("n",
"fnext",
(Sequence (
Sequence (
(Assignment ("fnow", Integer 0)),
(Assignment ("fnext", Integer 1))
),
(While (
(BCmpGreater (Variable "n", Integer 1)),
(Sequence (
(Sequence (
(Assignment ("tmp", Plus (Variable "fnow", Variable "fnext"))),
(Assignment ("fnow", Variable "fnext"))
)),
(Sequence (
(Assignment ("fnext", Variable "tmp")),
(Assignment ("n", Minus (Variable "n", Integer 1)))
))
))))
))
)
;;
Printf.printf "%d\n" (reduce 48 program)
;;
(* -------------------------------------------------------------------------- *)
(* Miller-Rabin primality test program *)
let program =
Main
("n",
"result",
Sequence (
(Assignment ("result", Integer 0)),
(Sequence (
(Sequence (
(Assignment ("s", Integer 0)),
(While (
(BCmp (Integer 0,
Modulo (
Division (
(Minus (Variable "n", Integer 1)),
(Power (Integer 2, Variable "s"))),
(Integer 2)
)
)
),
(Assignment ("s", Plus (Variable "s", Integer 1)))
))
)),
(Sequence (
(Assignment ("d", Division (Minus (Variable "n", Integer 1), Power (Integer 2, Variable "s")))),
(For (
(Assignment ("i", Integer 20)),
(BCmpGreater (Variable "i", Integer 0)),
(Assignment ("i", Minus (Variable "i", Integer 1))),
(Sequence (
Sequence (
(Assignment ("a", Plus (Rand (Minus (Variable "n", Integer 4)), Integer 2))),
(Assignment ("x", PowerMod (Variable "a", Variable "d", Variable "n")))),
Sequence (
(For (
(Assignment ("j", Integer 0)),
(BCmpLess (Variable "j", Variable "s")),
(Assignment ("j", Plus (Variable "j", Integer 1))),
(Sequence (
Sequence (
(Assignment ("y", PowerMod (Variable "x", Integer 2, Variable "n"))),
(If (
(BAnd (BAnd (BCmp (Variable "y", Integer 1), BNot (BCmp (Variable "x", Integer 1))), BNot (BCmp (Variable "x", Minus (Variable "n", Integer 1))))),
(Assignment ("result", Integer 1)),
(Skip)
))),
(Assignment ("x", Variable "y"))
))
)),
(If (
(BNot (BCmp (Variable "y", Integer 1))),
(Assignment ("result", Integer 1)),
(Skip)
)))
))
))
))
))
)
)
;;
(* should return 0 because prime *)
Printf.printf "%d\n" (reduce 179424673 program)
;;
(* sould return 1 because not prime *)
Printf.printf "%d\n" (reduce 179424675 program)
;;