make Vec.t abstract and document it; remove ugly hacks

This commit is contained in:
Simon Cruanes 2014-11-03 15:25:07 +01:00
parent ccb521e41f
commit f11fb2477b
4 changed files with 94 additions and 34 deletions

View file

@ -15,9 +15,13 @@ type 'a t = { mutable dummy: 'a; mutable data : 'a array; mutable sz : int }
let make capa d = {data = Array.make capa d; sz = 0; dummy = d} let make capa d = {data = Array.make capa d; sz = 0; dummy = d}
let make_empty d = {data = [||]; sz=0; dummy=d }
let init capa f d = {data = Array.init capa (fun i -> f i); sz = capa; dummy = d} let init capa f d = {data = Array.init capa (fun i -> f i); sz = capa; dummy = d}
let from_array data sz d = {data = data; sz = sz; dummy = d} let from_array data sz d =
assert (sz <= Array.length data);
{data = data; sz = sz; dummy = d}
let from_list l sz d = let from_list l sz d =
let l = ref l in let l = ref l in
@ -28,7 +32,9 @@ let clear s = s.sz <- 0
let shrink t i = assert (i >= 0 && i<=t.sz); t.sz <- t.sz - i let shrink t i = assert (i >= 0 && i<=t.sz); t.sz <- t.sz - i
let pop t = assert (t.sz >=1); t.sz <- t.sz - 1 let pop t =
if t.sz = 0 then invalid_arg "vec.pop";
t.sz <- t.sz - 1
let size t = t.sz let size t = t.sz
@ -56,39 +62,25 @@ let push t e =
t.data.(t.sz) <- e; t.data.(t.sz) <- e;
t.sz <- t.sz + 1 t.sz <- t.sz + 1
let push_none t =
if is_full t then grow_to_double_size t;
t.data.(t.sz) <- t.dummy;
t.sz <- t.sz + 1
let last t = let last t =
let e = t.data.(t.sz - 1) in if t.sz = 0 then invalid_arg "vec.last";
assert (not (e == t.dummy)); t.data.(t.sz - 1)
e
let get t i = let get t i =
assert (i < t.sz); if i < 0 || i >= t.sz then invalid_arg "vec.get";
let e = t.data.(i) in Array.unsafe_get t.data i
if e == t.dummy then raise Not_found
else e
let set t i v = let set t i v =
t.data.(i) <- v; if i < 0 || i > t.sz then invalid_arg "vec.set";
t.sz <- max t.sz (i + 1) t.sz <- max t.sz (i+1); (* can set first empty slot *)
Array.unsafe_set t.data i v
let set_size t sz = t.sz <- sz
let copy t = let copy t =
let data = t.data in let data = Array.copy t.data in
let len = Array.length data in {t with data; }
let data = Array.init len (fun i -> data.(i)) in
{ data=data; sz=t.sz; dummy = t.dummy }
let move_to t t' = let move_to t t' =
let data = t.data in t'.data <- Array.copy t.data;
let len = Array.length data in
let data = Array.init len (fun i -> data.(i)) in
t'.data <- data;
t'.sz <- t.sz t'.sz <- t.sz
@ -118,6 +110,15 @@ let iter f t =
f (get t i) f (get t i)
done done
let fold f acc t =
let rec _fold f acc t i =
if i=t.sz
then acc
else
let acc' = f acc (Array.unsafe_get t.data i) in
_fold f acc' t (i+1)
in _fold f acc t 0
(* (*
template<class V, class T> template<class V, class T>
static inline void remove(V& ts, const T& t) static inline void remove(V& ts, const T& t)

View file

@ -11,29 +11,82 @@
(* *) (* *)
(**************************************************************************) (**************************************************************************)
type 'a t = { mutable dummy: 'a; mutable data : 'a array; mutable sz : int } type 'a t
(** Abstract type of vectors of 'a *)
val make : int -> 'a -> 'a t val make : int -> 'a -> 'a t
(** [make cap dummy] creates a new vector filled with [dummy]. The vector
is initially empty but its underlying array has capacity [cap].
[dummy] will stay alive as long as the vector *)
val make_empty : 'a -> 'a t
(** Vector with an empty capacity. The only argument is the dummy. *)
val init : int -> (int -> 'a) -> 'a -> 'a t val init : int -> (int -> 'a) -> 'a -> 'a t
(** Same as {!Array.init}, but also with a dummy element *)
val from_array : 'a array -> int -> 'a -> 'a t val from_array : 'a array -> int -> 'a -> 'a t
(** [from_array arr size dummy] takes ownership of [data] (no copy)
to create a vector. [size] is the length of the slice of [data] that is
used ([size <= Array.length data] must hold) *)
val from_list : 'a list -> int -> 'a -> 'a t val from_list : 'a list -> int -> 'a -> 'a t
val clear : 'a t -> unit val clear : 'a t -> unit
(** Set size to 0, doesn't free elements *)
val shrink : 'a t -> int -> unit val shrink : 'a t -> int -> unit
val pop : 'a t -> unit val pop : 'a t -> unit
(** Pop last element
@raise Invalid_argument if the vector is empty *)
val size : 'a t -> int val size : 'a t -> int
val is_empty : 'a t -> bool val is_empty : 'a t -> bool
val grow_to : 'a t -> int -> unit val grow_to : 'a t -> int -> unit
val grow_to_double_size : 'a t -> unit val grow_to_double_size : 'a t -> unit
val grow_to_by_double : 'a t -> int -> unit val grow_to_by_double : 'a t -> int -> unit
val is_full : 'a t -> bool val is_full : 'a t -> bool
(** Is the capacity of the vector equal to the number of its elements? *)
val push : 'a t -> 'a -> unit val push : 'a t -> 'a -> unit
val push_none : 'a t -> unit
val last : 'a t -> 'a val last : 'a t -> 'a
(** Last element, or
@raise Invalid_argument if the vector is empty *)
val get : 'a t -> int -> 'a val get : 'a t -> int -> 'a
(** get the element at the given index, or
@raise Invalid_argument if the index is not valid *)
val set : 'a t -> int -> 'a -> unit val set : 'a t -> int -> 'a -> unit
val set_size : 'a t -> int -> unit (** set the element at the given index, either already set or the first
free slot if [not (is_full vec)], or
@raise Invalid_argument if the index is not valid *)
val copy : 'a t -> 'a t val copy : 'a t -> 'a t
(** Fresh copy *)
val move_to : 'a t -> 'a t -> unit val move_to : 'a t -> 'a t -> unit
(** [move_to a b] copies the content of [a] to [b], discarding [b]'s old content *)
val remove : 'a t -> 'a -> unit val remove : 'a t -> 'a -> unit
(** Uses [(==)] for comparison *)
val fast_remove : 'a t -> 'a -> unit val fast_remove : 'a t -> 'a -> unit
(** Remove element without preserving order (swap with last element) *)
val sort : 'a t -> ('a -> 'a -> int) -> unit val sort : 'a t -> ('a -> 'a -> int) -> unit
(** Sort in place the array *)
val iter : ('a -> unit) -> 'a t -> unit val iter : ('a -> unit) -> 'a t -> unit
(** Iterate on elements *)
val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
(** Fold over elements *)

View file

@ -160,7 +160,7 @@ module Make (F : Formula_intf.S)
let var_bump_activity v = let var_bump_activity v =
v.weight <- v.weight +. env.var_inc; v.weight <- v.weight +. env.var_inc;
if v.weight > 1e100 then begin if v.weight > 1e100 then begin
for i = 0 to env.vars.Vec.sz - 1 do for i = 0 to (Vec.size env.vars) - 1 do
(Vec.get env.vars i).weight <- (Vec.get env.vars i).weight *. 1e-100 (Vec.get env.vars i).weight <- (Vec.get env.vars i).weight *. 1e-100
done; done;
env.var_inc <- env.var_inc *. 1e-100; env.var_inc <- env.var_inc *. 1e-100;
@ -172,7 +172,7 @@ module Make (F : Formula_intf.S)
let clause_bump_activity c = let clause_bump_activity c =
c.activity <- c.activity +. env.clause_inc; c.activity <- c.activity +. env.clause_inc;
if c.activity > 1e20 then begin if c.activity > 1e20 then begin
for i = 0 to env.learnts.Vec.sz - 1 do for i = 0 to (Vec.size env.learnts) - 1 do
(Vec.get env.learnts i).activity <- (Vec.get env.learnts i).activity <-
(Vec.get env.learnts i).activity *. 1e-20; (Vec.get env.learnts i).activity *. 1e-20;
done; done;

View file

@ -63,18 +63,24 @@ module Make (F : Formula_intf.S) = struct
and dummy_atom = and dummy_atom =
{ var = dummy_var; { var = dummy_var;
lit = dummy_lit; lit = dummy_lit;
watched = {Vec.dummy=dummy_clause; data=[||]; sz=0}; watched = Obj.magic 0;
(* should be [Vec.make_empty dummy_clause]
but we have to break the cycle *)
neg = dummy_atom; neg = dummy_atom;
is_true = false; is_true = false;
aid = -102 } aid = -102 }
and dummy_clause =
let dummy_clause =
{ name = ""; { name = "";
atoms = {Vec.dummy=dummy_atom; data=[||]; sz=0}; atoms = Vec.make_empty dummy_atom;
activity = -1.; activity = -1.;
removed = false; removed = false;
learnt = false; learnt = false;
cpremise = [] } cpremise = [] }
let () =
dummy_atom.watched <- Vec.make_empty dummy_clause
module MA = Map.Make(F) module MA = Map.Make(F)
type varmap = var MA.t type varmap = var MA.t