mirror of
https://github.com/AdaCore/why3.git
synced 2026-02-12 12:34:55 -08:00
161 lines
5.3 KiB
Plaintext
161 lines
5.3 KiB
Plaintext
|
|
use int.Int
|
|
use bintree.AVL
|
|
use coma.Std
|
|
|
|
let unTree (t: tree) (onNode [] (l:tree) (x: elt) (r:tree)) (onLeaf) =
|
|
any
|
|
[ node (h: int) (x: elt) (l r: tree) ->
|
|
{ t = N h l x r } (! onNode {l} {x} {r})
|
|
| leaf ->
|
|
{ t = E } (! onLeaf) ]
|
|
|
|
let rotate_left (t: tree) (return (r: tree)) =
|
|
unTree {t} (fun (a:tree) (x:elt) (r:tree) ->
|
|
unTree {r} (fun (b:tree) (y:elt) (c:tree) ->
|
|
return {node (node a x b) y c})
|
|
fail) fail
|
|
|
|
let rotate_right (t: tree) (return (r: tree)) =
|
|
unTree {t} (fun (l:tree) (y:elt) (c:tree) ->
|
|
unTree {l} (fun (a:tree) (x:elt) (b:tree) ->
|
|
return {node a x (node b y c)})
|
|
fail) fail
|
|
|
|
let join_right (l: tree) (x: elt) (r: tree) (return (t: tree)) =
|
|
{ bst l && tree_lt l x } { bst r && lt_tree x r }
|
|
{ wf l && wf r } { avl l && avl r } { height l >= height r + 2 } (!
|
|
any
|
|
)
|
|
[ return (t: tree) ->
|
|
{ bst t } { forall y. mem y t <-> (mem y l || y=x || mem y r) }
|
|
{ wf t } { avl t }
|
|
{ height t = height l ||
|
|
height t = height l + 1 && match t with
|
|
| N _ rl _ rr ->
|
|
height rl = height l - 1 && height rr = height l
|
|
| _ -> false end }
|
|
(! return {t}) ]
|
|
|
|
(* TODO join_right, join_left
|
|
= match l with
|
|
| N _ ll lx lr ->
|
|
if ht lr <= ht r + 1 then
|
|
let t = node lr x r in
|
|
if ht t <= ht ll + 1 then node ll lx t
|
|
else rotate_left (node ll lx (rotate_right t))
|
|
else
|
|
let t = join_right lr x r in
|
|
let t' = node ll lx t in
|
|
if ht t <= ht ll + 1 then t' else rotate_left t'
|
|
(* The CRITICAL postcondition is used here, when `rotate_left`
|
|
is used, to show that the rotated tree is indeed an AVL. *)
|
|
| E -> absurd
|
|
end
|
|
*)
|
|
|
|
let join_left (l: tree) (x: elt) (r: tree) (return (t: tree)) =
|
|
{ bst l && tree_lt l x } { bst r && lt_tree x r }
|
|
{ wf l && wf r } { avl l && avl r } { height r >= height l + 2 } (!
|
|
any
|
|
)
|
|
[ return (t: tree) ->
|
|
{ bst t } { forall y. mem y t <-> (mem y l || y=x || mem y r) }
|
|
{ wf t } { avl t }
|
|
{ height t = height r ||
|
|
height t = height r + 1 && match t with
|
|
| N _ rl _ rr ->
|
|
height rr = height r - 1 && height rl = height r
|
|
| _ -> false end }
|
|
(! return {t}) ]
|
|
(*
|
|
= match r with
|
|
| N _ rl rx rr ->
|
|
if ht rl <= ht l + 1 then
|
|
let t = node l x rl in
|
|
if ht t <= ht rr + 1 then node t rx rr
|
|
else rotate_right (node (rotate_left t) rx rr)
|
|
else
|
|
let t = join_left l x rl in
|
|
let t' = node t rx rr in
|
|
if ht t <= ht rr + 1 then t' else rotate_right t'
|
|
| E -> absurd
|
|
end
|
|
*)
|
|
|
|
let join (l: tree) (x: elt) (r: tree) (return (r: tree)) =
|
|
{ bst l && tree_lt l x } { bst r && lt_tree x r }
|
|
{ wf l && wf r } { avl l && avl r } (!
|
|
if { ht l > ht r + 1 }
|
|
(-> join_right {l} {x} {r} return)
|
|
(-> if { ht r > ht l + 1 } (-> join_left {l} {x} {r} return)
|
|
(-> return {node l x r})))
|
|
[ return (t:tree)
|
|
{ wf t && avl t }
|
|
{ bst t }
|
|
{ forall y. mem y t <-> (mem y l || y=x || mem y r) }
|
|
-> return {t} ]
|
|
|
|
let rec split_last (t: tree) (return (r: tree) (m: elt)) =
|
|
unTree {t}
|
|
(fun (l: tree) (x: elt) (r: tree) ->
|
|
{ wf t && bst t && avl t } (!
|
|
if {r=E} (-> return {l} {x})
|
|
(-> split_last {r} (fun (r':tree) (m:elt) ->
|
|
join {l} {x} {r'} (fun (r:tree) ->
|
|
return {r} {m}))))
|
|
[ return (r: tree) (m: elt)
|
|
{ wf r && bst r && avl r }
|
|
{ forall x. mem x t <-> (mem x r && lt x m || x=m) }
|
|
{ tree_lt r m }
|
|
-> return {r} {m} ])
|
|
fail
|
|
|
|
(* no need for a spec here => join2 is fully inlined *)
|
|
let join2 (l r: tree) (return (t: tree)) =
|
|
if {l=E} (-> return {r})
|
|
(-> split_last {l} (fun (l:tree) (k:elt) ->
|
|
join {l} {k} {r} return))
|
|
|
|
let rec split (t: tree) (y: elt) (return (l: tree) (b: bool) (r: tree)) =
|
|
unTree {t}
|
|
(fun (l:tree) (x:elt) (r:tree) ->
|
|
{ wf t && bst t && avl t }
|
|
(!
|
|
if {y=x} (-> return {l} {true} {r})
|
|
(-> if {lt y x} (-> split {l} {y} (fun (ll:tree) (b:bool) (lr:tree) ->
|
|
join {lr} {x} {r} (fun (r':tree) ->
|
|
return {ll} {b} {r'})))
|
|
(-> split {r} {y} (fun (rl:tree) (b:bool) (rr:tree) ->
|
|
join {l} {x} {rl} (fun (l':tree) ->
|
|
return {l'} {b} {rr}))))
|
|
)
|
|
[return (l: tree) (b: bool) (r: tree) ->
|
|
{ wf l && bst l && avl l } { wf r && bst r && avl r }
|
|
{ tree_lt l y } { lt_tree y r }
|
|
{ forall x. mem x t <-> (mem x l || mem x r || b && x=y) }
|
|
(! return {l} {b} {r}) ]
|
|
)
|
|
(-> return {E} {false} {E})
|
|
|
|
let insert (x: elt) (t: tree) (return (r: tree)) =
|
|
{ wf t && bst t && avl t } (!
|
|
split {t} {x} (fun (l:tree) (_b:bool) (r:tree) ->
|
|
join {l} {x} {r} return)
|
|
)
|
|
[ return (r:tree) ->
|
|
{ wf r && bst r && avl r }
|
|
{ forall y. mem y r <-> (mem y t || y=x) }
|
|
(! return {r}) ]
|
|
|
|
let delete (x: elt) (t: tree) (return (r: tree)) =
|
|
{ wf t && bst t && avl t } (!
|
|
split {t} {x} (fun (l: tree) (b: bool) (r: tree) ->
|
|
join2 {l} {r} return)
|
|
)
|
|
[ return (r:tree) ->
|
|
{ wf r && bst r && avl r }
|
|
{ forall y. mem y r <-> (mem y t && y<>x) }
|
|
(! return {r}) ]
|
|
|