Ocaml错误:回答错误(请帮助修复)

Ocaml错误:回答错误(请帮助修复),ocaml,Ocaml,我已经被这个问题困扰了一个多小时了。所以测试台在底部,答案应该是120,但我一直得到20。我相信它只做5*4,而不是3*2和1的其余部分。 有什么问题吗 我试着把其他的都修好,但它们似乎都是对的。这是计算错误吗?这是问题吗 type exp = | NUM of int | TRUE | FALSE | UNIT | VAR of id | ADD of exp * exp | SUB of exp * exp | MUL of exp * exp | DIV of ex

我已经被这个问题困扰了一个多小时了。所以测试台在底部,答案应该是120,但我一直得到20。我相信它只做5*4,而不是3*2和1的其余部分。 有什么问题吗

我试着把其他的都修好,但它们似乎都是对的。这是计算错误吗?这是问题吗

type exp =
  | NUM of int | TRUE | FALSE | UNIT
  | VAR of id
  | ADD of exp * exp
  | SUB of exp * exp
  | MUL of exp * exp
  | DIV of exp * exp
  | EQUAL of exp * exp
  | LESS of exp * exp
  | NOT of exp
  | SEQ of exp * exp                 (* sequence *)
  | IF of exp * exp * exp            (* if-then-else *)
  | WHILE of exp * exp               (* while loop *)
  | LETV of id * exp * exp           (* variable binding *)
  | LETF of id * id list * exp * exp (* procedure binding *)
  | CALLV of id * exp list           (* call by value *)
  | CALLR of id * id list            (* call by referenece *)
  | RECORD of (id * exp) list        (* record construction *)
  | FIELD of exp * id                (* access record field *)
  | ASSIGN of id * exp               (* assgin to variable *)
  | ASSIGNF of exp * id * exp        (* assign to record field *)
  | WRITE of exp
and id = string

type loc = int
type value =
| Num of int
| Bool of bool
| Unit
| Record of record 
and record = (id * loc) list
type memory = (loc * value) list
type env = binding list
and binding = LocBind of id * loc | ProcBind of id * proc
and proc = id list * exp * env

(********************************)
(*     Handling environment     *)
(********************************)

let rec lookup_loc_env : id -> env -> loc
= fun x env ->
  match env with
  | [] -> raise(Failure ("Variable "^x^" is not included in environment"))
  | hd::tl ->
    begin match hd with
    | LocBind (id,l) -> if(x=id) then l else lookup_loc_env x tl
    | ProcBind _ -> lookup_loc_env x tl
    end

let rec lookup_proc_env : id -> env -> proc
= fun x env ->
  match env with
  | [] -> raise(Failure ("Variable "^x^" is not included in environment"))
  | hd::tl ->
    begin match hd with
    | LocBind _ -> lookup_proc_env x tl
    | ProcBind (id,binding) -> if (x=id) then binding else lookup_proc_env x tl
    end

let extend_env : binding -> env -> env
= fun e env -> e::env

let empty_env = []`enter code here`
(***************************)
(*     Handling memory     *)
(***************************)

let rec lookup_mem : loc -> memory -> value
= fun l mem ->
  match mem with
  | [] -> raise(Failure ("location "^(string_of_int l)^" is not included in memory"))
  | (loc,v)::tl -> if(l=loc) then v else lookup_mem l tl

let extend_mem : (loc * value) -> memory -> memory
= fun (l,v) mem -> (l,v)::mem

let empty_mem = []

(***************************)
(*     Handling record     *)
(***************************)

let rec lookup_record : id -> record -> loc
= fun id record -> 
  match record with
    | [] -> raise(Failure ("field "^ id ^" is not included in record"))
    | (x,l)::tl -> if(id=x) then l else lookup_record id tl


let extend_record : (id * loc) -> record -> record
= fun (x,l) record -> (x,l)::record

let empty_record = []

(***************************)

let counter = ref 0
let new_location () = counter:=!counter+1;!counter

exception NotImplemented
exception UndefinedSemantics

let rec list_fold2 : ('a -> 'b -> 'c -> 'c)-> 'a list -> 'b list -> 'c -> 'c
= fun func l1 l2 acc ->
  match (l1,l2) with
  | ([],[]) -> acc
  | (hd1::tl1,hd2::tl2) -> list_fold2 func tl1 tl2 (func hd1 hd2 acc)
  | _ -> raise (Failure "two lists have different length")

let rec list_fold : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b
= fun func l acc ->
  match l with
  | [] -> acc
  | hd::tl -> list_fold func tl (func hd acc)

let value2str : value -> string
= fun v ->
  match v with
  | Num n -> string_of_int n
  | Bool b -> string_of_bool b
  | Unit -> "unit"
  | Record _ -> "record" 

let rec eval_aop : env -> memory -> exp -> exp -> (int -> int -> int) -> (value * memory)
= fun env mem e1 e2 op ->
  let (v1,mem1) = eval env mem e1 in
  let (v2,mem2) = eval env mem1 e2 in
  match (v1,v2) with
  | (Num n1, Num n2) -> (Num (op n1 n2), mem2)
  | _ -> raise (Failure "arithmetic operation type error")

and eval : env -> memory -> exp -> (value * memory) 
=fun env mem e -> 
   match e with
  | NUM n -> (Num n, mem) 
  | TRUE -> (Bool true, mem)
  | FALSE -> (Bool false, mem)
  | UNIT -> (Unit, mem)
  | VAR x -> ((lookup_mem (lookup_loc_env x env) mem ), mem )
  | ADD (e1, e2) -> eval_aop env mem e1 e2 (+) 
  | SUB (e1, e2) -> eval_aop env mem e1 e2 (-)
  | MUL (e1, e2) -> eval_aop env mem e1 e2 ( * )
  | DIV (e1, e2) -> eval_aop env mem e1 e2 (/)
  |EQUAL (e1, e2) ->
      let (v1, mem1) = eval env mem e1 in
      let (v2, mem2) = eval env mem1 e2 in
        if v1 = v2 then (Bool true, mem2) else (Bool false, mem2)
  |LESS (e1, e2) -> 
      let (v1, mem1) = eval env mem e1 in
      let (v2, mem2) = eval env mem1 e2 in
      begin match (v1, v2) with 
        | (Num n1, Num n2) -> 
        if Num n1 < Num n2 then (Bool true, mem2) else (Bool false, mem2)
        | _ -> raise (UndefinedSemantics)
        end
        
  |NOT (e1) ->
    let (b, mem1) = eval env mem e1 in
      if b = b then (Bool false,mem1) else (Bool true,mem1)
  |SEQ (e1, e2) ->
    let (v1, mem1) = eval env mem e1 in 
    let (v2, mem2) = eval env mem1 e2 in
        (v2,mem2)
  |IF (e1,e2,e3) -> 
    (match (eval env mem e1) with 
      | (Bool true, mem1) -> eval env mem1 e1
      | (Bool false, mem1) -> eval env mem1 e2
      | _ -> raise (UndefinedSemantics) )
  |WHILE (e1,e2) ->
   begin match (eval env mem e1) with
      | (Bool true, mem1) ->
          let (v1, mem2) = eval env mem1 e2 in
            eval env mem2 e2
      | (Bool false, mem1) -> (Unit, mem1)
      | _ -> raise (UndefinedSemantics) 
      
      end
  |LETV (x,e1,e2) ->
    let (v1, mem1) = eval env mem e1 in
    let a = LocBind (x, (new_location()) ) in 
    let (v2,mem2) = eval (extend_env a env) (extend_mem ((lookup_loc_env x)(extend_env a env), v1) mem1 )e2 in
    (v2,mem2)
    
  | ASSIGN (x,e1) ->
    let (v1, mem1) = eval env mem e1 in 
    (v1, extend_mem ((lookup_loc_env x env) , (v1) ) mem1) 
    
  | WRITE e -> 
    let (v1,mem1) = eval env mem e in
    let _ = print_endline(value2str v1) in
    (v1,mem1)
  
  
 | _ -> raise NotImplemented
;;
      
    
    

let runb : exp -> value 
=fun exp -> let (v, _) = eval empty_env empty_mem exp in v;;



let test = LETV ("ret", NUM 1,
LETV ("n", NUM 5,
SEQ (
WHILE (LESS (NUM 0, VAR "n"),
SEQ (
ASSIGN ("ret", MUL (VAR "ret", VAR "n")),
ASSIGN ("n", SUB (VAR "n", NUM 1))
)
),
VAR "ret")))
;;

runb test;;
type exp=
|整数|真|假|单位数
|id变量
|添加exp*exp
|exp*exp的子项
|经验倍数*exp
|exp*exp的DIV
|等于exp*exp
|减去exp*exp
|不属于经验
|exp*exp(*序列*)的序号
|IF of exp*exp*exp(*IF then else*)
|exp*exp(*WHILE loop*)的WHILE
|id*exp*exp(*变量绑定*)的LETV
|id*id列表*exp*exp(*过程绑定*)的LETF
|id*exp列表(*按值调用*)的调用
|id*id列表的调用器(*引用调用*)
|(id*exp)列表的记录(*记录构造*)
|exp*id的字段(*访问记录字段*)
|将id*exp(*关联到变量*)赋值
|exp*id*exp(*分配给记录字段*)的赋值
|编写exp
和id=string
类型loc=int
类型值=
|整数的个数
|布尔的布尔
|单位
|记录
和记录=(id*loc)列表
类型内存=(loc*值)列表
类型env=绑定列表
and binding=id的LocBind*loc | id的ProcBind*proc
和proc=id list*exp*env
(********************************)
(*处理环境*)
(********************************)
让记录查找\u loc\u env:id->env->loc
=乐趣x环境->
匹配环境
|[]->raise(失败(“环境中不包括变量“^x^”))
|hd::tl->
开始匹配hd
|LocBind(id,l)->如果(x=id),那么l else查找\u loc\u env x tl
|ProcBind->lookup\u loc\u env x tl
终止
让rec lookup\u proc\u env:id->env->proc
=乐趣x环境->
匹配环境
|[]->raise(失败(“环境中不包括变量“^x^”))
|hd::tl->
开始匹配hd
|LocBind->查找程序环境x tl
|ProcBind(id,binding)->if(x=id)然后binding else查找\u proc\u env x tl
终止
让我们扩展_env:binding->env->env
=娱乐环境->娱乐环境
让empty_env=[]在这里输入代码`
(***************************)
(*处理内存*)
(***************************)
让记录查找\u mem:loc->memory->value
=fun l mem->
将mem与
|[]->raise(失败(“位置”^(字符串^不包括在内存中”))
|(loc,v)::tl->if(l=loc)然后v else查找\u mem l tl
让我们扩展_mem:(loc*value)->内存->内存
=乐趣(l,v)mem->(l,v)::mem
设为空_mem=[]
(***************************)
(*处理记录*)
(***************************)
让rec查找\u记录:id->record->loc
=乐趣id记录->
将记录与
|[]->raise(失败(“记录中不包括字段“^id^”))
|(x,l)::tl->if(id=x)那么l else查找\u记录id tl
让我们扩展_记录:(id*loc)->记录->记录
=乐趣(x,l)记录->(x,l)::记录
让空_记录=[]
(***************************)
设计数器=ref 0
让新位置()=计数器:=!计数器+1;!柜台
异常未实现
异常未定义语义
让rec list_fold2:('a->'b->'c->'c)->'a list->'b list->'c->'c
=乐趣功能l1 l2 acc->
将(l1,l2)与
|([],[])->acc
|(hd1::tl1,hd2::tl2)->列表功能tl1 tl2(功能hd1 hd2 acc)
|->raise(失败“两个列表长度不同”)
让rec list折叠:('a->'b->'b)->'a list->'b->'b
=娱乐功能附件->
匹配
|[]->acc
|hd::tl->list_fold func tl(func hd acc)
让value2str:value->string
=乐趣v->
匹配
|Num n->string\u of\u int n
|布尔b->布尔b的字符串
|单位->“单位”
|记录-->“记录”
让记录评估aop:env->memory->exp->exp->(int->int->int)-->(值*内存)
=娱乐环境成员e1 e2 op->
let(v1,mem1)=评估环境mem e1 in
let(v2,mem2)=eval env mem1 e2 in
将(v1,v2)与
|(Num n1,Num n2)->(Num(op n1 n2),mem2)
|->raise(失败“算术运算类型错误”)
和eval:env->memory->exp->(值*内存)
=娱乐环境成员->
匹配
|NUM n->(NUM n,mem)
|正确->(布尔正确,内存)
|假->(布尔假,内存)
|单位->(单位,成员)
|变量x->(查找内存(查找位置环境x环境)内存),内存
|添加(e1,e2)->评估aop环境成员e1 e2(+)
|SUB(e1,e2)->评估aop环境成员e1 e2(-)
|MUL(e1,e2)->评估aop环境成员e1 e2(*)
|分区(e1,e2)->评估aop环境成员e1 e2(/)
|相等(e1,e2)->
let(v1,mem1)=评估环境mem e1 in
let(v2,mem2)=eval env mem1 e2 in
如果v1=v2,则(布尔真,mem2)否则(布尔假,mem2)
|减去(e1,e2)->
let(v1,mem1)=评估环境mem e1 in
let(v2,mem2)=eval env mem1 e2 in
开始匹配(v1、v2)
|(数量n1,数量n2)->
如果Num n1
设(b,mem1)=eval env mem e1 in
如果b=b,则(Bool false,mem1)否则(Bool true,mem1)
|序号(e1,e2)->
let(v1,mem1)=评估环境mem e1 in
let(v2,mem2)=eval env mem1 e2 in
(v2,mem2)
|如果(e1、e2、e3)->
(将(评估环境成员e1)与
|(Bool true,mem1)->eval env mem1 e1
|(Bool false,mem1)->评估环境mem1 e2
|->升起(未定义指令))
|而(e1,e2)->
开始匹配(eval env mem e1)
|(Bool-true,mem1)->
let(v1,mem2)=eval env mem1 e2 in
评估环境成员2 e2
|(Bool false,mem1)->(单元,mem1)
|提升(未定义的指令)
终止
|乐视网(x、e1、e2)->
let(v1,mem1)=评估环境mem e1 in
将a=LocBind(x,(new_location())放入
let(v2,mem2)=