Function 什么';在部分函数中重新定义和组合的ocaml代码的含义是什么
我正在读《实用逻辑和自动推理手册》。它有一些代码来定义文件Function 什么';在部分函数中重新定义和组合的ocaml代码的含义是什么,function,ocaml,first-order-logic,formal-methods,Function,Ocaml,First Order Logic,Formal Methods,我正在读《实用逻辑和自动推理手册》。它有一些代码来定义文件lib.ml中的有限部分函数。我无法理解部分函数中重新定义和组合代码的含义。newbranch子功能的用途是什么?代码如下: type ('a,'b)func = Empty | Leaf of int * ('a*'b)list | Branch of int * int * ('a,'b)func * ('a,'b)func;; (* -----------------------------------------
lib.ml
中的有限部分函数。我无法理解部分函数中重新定义和组合代码的含义。newbranch
子功能的用途是什么?代码如下:
type ('a,'b)func =
Empty
| Leaf of int * ('a*'b)list
| Branch of int * int * ('a,'b)func * ('a,'b)func;;
(* ------------------------------------------------------------------------- *)
(* Redefinition and combination. *)
(* ------------------------------------------------------------------------- *)
let (|->),combine =
let newbranch p1 t1 p2 t2 =
let zp = p1 lxor p2 in
let b = zp land (-zp) in
let p = p1 land (b - 1) in
if p1 land b = 0 then Branch(p,b,t1,t2)
else Branch(p,b,t2,t1) in
let rec define_list (x,y as xy) l =
match l with
(a,b as ab)::t ->
let c = Pervasives.compare x a in
if c = 0 then xy::t
else if c < 0 then xy::l
else ab::(define_list xy t)
| [] -> [xy]
and combine_list op z l1 l2 =
match (l1,l2) with
[],_ -> l2
| _,[] -> l1
| ((x1,y1 as xy1)::t1,(x2,y2 as xy2)::t2) ->
let c = Pervasives.compare x1 x2 in
if c < 0 then xy1::(combine_list op z t1 l2)
else if c > 0 then xy2::(combine_list op z l1 t2) else
let y = op y1 y2 and l = combine_list op z t1 t2 in
if z(y) then l else (x1,y)::l in
let (|->) x y =
let k = Hashtbl.hash x in
let rec upd t =
match t with
Empty -> Leaf (k,[x,y])
| Leaf(h,l) ->
if h = k then Leaf(h,define_list (x,y) l)
else newbranch h t k (Leaf(k,[x,y]))
| Branch(p,b,l,r) ->
if k land (b - 1) <> p then newbranch p t k (Leaf(k,[x,y]))
else if k land b = 0 then Branch(p,b,upd l,r)
else Branch(p,b,l,upd r) in
upd in
let rec combine op z t1 t2 =
match (t1,t2) with
Empty,_ -> t2
| _,Empty -> t1
| Leaf(h1,l1),Leaf(h2,l2) ->
if h1 = h2 then
let l = combine_list op z l1 l2 in
if l = [] then Empty else Leaf(h1,l)
else newbranch h1 t1 h2 t2
| (Leaf(k,lis) as lf),(Branch(p,b,l,r) as br) ->
if k land (b - 1) = p then
if k land b = 0 then
(match combine op z lf l with
Empty -> r | l' -> Branch(p,b,l',r))
else
(match combine op z lf r with
Empty -> l | r' -> Branch(p,b,l,r'))
else
newbranch k lf p br
| (Branch(p,b,l,r) as br),(Leaf(k,lis) as lf) ->
if k land (b - 1) = p then
if k land b = 0 then
(match combine op z l lf with
Empty -> r | l' -> Branch(p,b,l',r))
else
(match combine op z r lf with
Empty -> l | r' -> Branch(p,b,l,r'))
else
newbranch p br k lf
| Branch(p1,b1,l1,r1),Branch(p2,b2,l2,r2) ->
if b1 < b2 then
if p2 land (b1 - 1) <> p1 then newbranch p1 t1 p2 t2
else if p2 land b1 = 0 then
(match combine op z l1 t2 with
Empty -> r1 | l -> Branch(p1,b1,l,r1))
else
(match combine op z r1 t2 with
Empty -> l1 | r -> Branch(p1,b1,l1,r))
else if b2 < b1 then
if p1 land (b2 - 1) <> p2 then newbranch p1 t1 p2 t2
else if p1 land b2 = 0 then
(match combine op z t1 l2 with
Empty -> r2 | l -> Branch(p2,b2,l,r2))
else
(match combine op z t1 r2 with
Empty -> l2 | r -> Branch(p2,b2,l2,r))
else if p1 = p2 then
(match (combine op z l1 l2,combine op z r1 r2) with
(Empty,r) -> r | (l,Empty) -> l | (l,r) -> Branch(p1,b1,l,r))
else
newbranch p1 t1 p2 t2 in
(|->),combine;;
type('a,'b)func=
空的
|int*('a*'b)列表的叶
|int*int*('a,'b)func*('a,'b)func;)的分支;;
(* ------------------------------------------------------------------------- *)
(*重新定义和组合。*)
(* ------------------------------------------------------------------------- *)
让(|->)合并=
让newbranch p1 t1 p2 t2=
设zp=p1 lx或p2 in
设b=zp落地(-zp)in
让p=p1着陆(b-1)in
如果p1接地b=0,则分支(p、b、t1、t2)
else分支(p、b、t2、t1)位于
让rec定义_列表(x,y为xy)l=
匹配
(a,b作为ab)::t->
设c=渗透性。比较x中的a
如果c=0,则xy::t
否则,如果c<0,则xy::l
else ab::(定义列表xy t)
|[]->[xy]
和组合_列表op z l1 l2=
将(l1,l2)与
[],[uuu2->l2
|_u,[]->l1
|((x1,y1为xy1)::t1,(x2,y2为xy2)::t2)->
设c=渗透性。比较x1 x2 in
如果c<0,则xy1::(组合列表操作z t1 l2)
如果c>0,则xy2::(组合列表操作z l1 t2)否则
设y=op y1 y2和l=组合列表op z t1 t2 in
如果z(y),那么l其他(x1,y)::l in
设(|->)x y=
设k=Hashtbl.hash x in
让我们记录一下=
匹配
空->叶(k[x,y])
|叶(h,l)->
如果h=k,则叶(h,定义_列表(x,y)l)
else newbranch h t k(叶(k,[x,y]))
|分支机构(p、b、l、r)->
如果k落在(b-1)p上,则新枝ptk(叶(k,[x,y]))
否则,如果k land b=0,则分支(p,b,upd l,r)
其他分支机构(p、b、l、upd r)
upd-in
让rec组合op z t1 t2=
将(t1,t2)与
空,->t2
|_389;,空->t1
|叶(h1,l1),叶(h2,l2)->
如果h1=h2,则
设l=组合_列表op z l1 l2 in
如果l=[],则清空else叶(h1,l)
else newbranch h1 t1 h2 t2
|(叶(k,lis)作为lf),(分支(p,b,l,r)作为br)->
如果k土地(b-1)=p,那么
如果k和b=0,则
(将联合收割机操作z和左前匹配)
空->r | l'->分支(p,b,l',r))
其他的
(将联合收割机操作z左前r与
空->l | r'->分支(p,b,l,r'))
其他的
纽伯兰k lf p br酒店
|(分支(p,b,l,r)作为br,(叶(k,lis)作为lf)->
如果k土地(b-1)=p,那么
如果k和b=0,则
(将联合收割机操作z l lf与
空->r | l'->分支(p,b,l',r))
其他的
(将联合收割机操作z r lf与
空->l | r'->分支(p,b,l,r'))
其他的
纽伯兰酒店
|分支(p1、b1、l1、r1),分支(p2、b2、l2、r2)->
如果b1r1 | l->分支(p1、b1、l、r1))
其他的
(将联合收割机操作z r1 t2与
空->l1 | r->分支(p1、b1、l1、r))
否则,如果b2r2 | l->分支(p2、b2、l、r2))
其他的
(将操作z t1 r2与
空->l2 | r->分支(p2、b2、l2、r))
否则,如果p1=p2,则
(匹配(组合操作z l1 l2,组合操作z r1 r2)和
(空,r)->r |(l,空)->l |(l,r)->分支(p1,b1,l,r))
其他的
新牧场p1 t1 p2 t2 in
(|->),联合收割机;;
你能给我解释一下这个代码的意思吗?这些树叫做帕特里夏树,它们是。 John Harrison将其用作有限部分函数,即。E不可变散列树是分部函数的唯一表示形式 要理解函数,必须理解树 树木解说
| int*('a*'b)列表的叶
叶子中的int参数是键的散列值。
哈希值后的列表是一个键-值对的排序关联列表,其中所有键都具有相同的哈希值。这些散列值的小端前缀将存储在分支中
如果二进制大端表示法中的k=00111001
,则1001
是k
的大端后缀或小端前缀。因为所有的整数都有固定的位数,所以前缀用zeor扩展。前缀在程序中类似于00001001
| int*int*('a,'b)func*('a,'b)func的分支
您应该将这些整数看作小端位数组,而不是整数。第一个int是两个子树的公共小端点前缀。第二个int标记第一个不同位的位置。这两个整数用作位掩码。在分支(p,b,t1,t2)
中,树t1
具有扩展p
的前缀,且0
位于b
位置。树t2
还有一个前缀,它扩展了p
,但在b
位置有1
以下是理解代码的一些规则:
- 每当你看到一棵
、t
或t1
时,它就是一棵帕特里夏树。(键入t2
)('a,'b)func
- 变量
、p
或p1
表示哈希值的二进制小端前缀(=大端后缀)。(键入p2
)int
- 变量
、b
、b1
等标记第一位tb2