plazowicz
plazowicz

Reputation: 41

OCaml recursive function

I'm new in OCaml. I wrote this code to reduce algebraic expressions:

type expr =
    | Int of int
    | Float of float
    | Add of expr*expr
    | Sub of expr*expr
    | Mult of expr*expr
    | Div of expr*expr
    | Minus of expr

let rec eval expression = match expression with
    | Add (e1, e2) -> (eval e1) +. (eval e2)
    | Sub (e1,e2) -> (eval e1) -. (eval e2)
    | Mult (e1,e2) -> (eval e1) *. (eval e2)
    | Div (e1, e2) -> (eval e1) /. (eval e2)
    | Minus (e1) -> -.(eval e1)
    | Int i -> (float) i
    | Float f -> f

let rec simplify_expr e = match e with
| Add (e1,e2) -> if (eval e1) == 0.0 then simplify_expr e2 
                                    else if (eval e2) == 0.0 then simplify_expr e1 
                                    else Add (simplify_expr e1, simplify_expr e2)
| Mult(e1,e2) -> if (eval e1) == 1.0 then simplify_expr e2 
                                    else if (eval e2) == 1.0 then simplify_expr e1 
                                    else Mult (simplify_expr e1, simplify_expr e2)
| Sub (e1, e2) -> if (eval e1) == 0.0 then simplify_expr e2 
                                    else if (eval e2) == 0.0 then simplify_expr e1 
                                    else Sub (simplify_expr e1, simplify_expr e2)
| Div (e1, e2) -> if (eval e1) == 1.0 then simplify_expr e2 
                                    else if (eval e2) == 1.0 then simplify_expr e1 
                                    else Div (simplify_expr e1, simplify_expr e2)
| Int i -> e
| Minus e1 -> simplify_expr(e1)
| Float f -> e

I call simplify_expr in this way:

Expr.simplify_expr Expr.Mult (Expr.Int 4, Expr.Add (Expr.Int 1, Expr.Int 0));;

And I've got wrong answer:

- : Expr.expr = Expr.Mult (Expr.Int 4, Expr.Add (Expr.Int 1, Expr.Int 0))

Below I paste call's stack.

Expr.simplify_expr <--
  Expr.Mult (Expr.Int 4, Expr.Add (Expr.Int 1, Expr.Int 0))
Expr.eval <-- Expr.Int 4
Expr.eval --> 4.
Expr.eval <-- Expr.Add (Expr.Int 1, Expr.Int 0)
Expr.eval <-- Expr.Int 0
Expr.eval --> 0.
Expr.eval <-- Expr.Int 1
Expr.eval --> 1.
Expr.eval --> 1.
Expr.simplify_expr <-- Expr.Add (Expr.Int 1, Expr.Int 0)
Expr.eval <-- Expr.Int 1
Expr.eval --> 1.
Expr.eval <-- Expr.Int 0
Expr.eval --> 0.
Expr.simplify_expr <-- Expr.Int 0
Expr.simplify_expr --> Expr.Int 0
Expr.simplify_expr <-- Expr.Int 1
Expr.simplify_expr --> Expr.Int 1
Expr.simplify_expr --> Expr.Add (Expr.Int 1, Expr.Int 0)
Expr.simplify_expr <-- Expr.Int 4
Expr.simplify_expr --> Expr.Int 4
Expr.simplify_expr -->
  Expr.Mult (Expr.Int 4, Expr.Add (Expr.Int 1, Expr.Int 0))
- : Expr.expr = Expr.Mult (Expr.Int 4, Expr.Add (Expr.Int 1, Expr.Int 0))

I have no idea, why after return of eval with 1 (9th line) simplify_expr was called with Add. Anybody can help ?

Upvotes: 2

Views: 618

Answers (1)

jrouquie
jrouquie

Reputation: 4405

Replace == with =. See for instance Does != have meaning in OCaml? .

Not the question, but also check the Sub, Div and Minus cases of simplify_expr: 0 - e2 is not e2 and 1 / e2 is not e2...

Upvotes: 9

Related Questions