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
    b2
    等标记第一位t