Ocaml错误:回答错误(请帮助修复)
我已经被这个问题困扰了一个多小时了。所以测试台在底部,答案应该是120,但我一直得到20。我相信它只做5*4,而不是3*2和1的其余部分。 有什么问题吗 我试着把其他的都修好,但它们似乎都是对的。这是计算错误吗?这是问题吗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
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)=