struct

 open Sugar;;

 
 (**

Generalization

*)


 
 (** Head and tail generalisation *)


 
 (** Similar to the standard List.hd, but retrieve the list of first elements (by default n=1 as in List.hd). Thus, the result is a list. *)

 let rec head ?(n:int=1) (l:'a list) : ('a list) = 
  if n<=0 then [] else let n = (n-1) in 
  match l with 
  | []   -> []
  | x::r -> x::(head ~n r) 
 ;;

 
 (** Similar to the standard List.tl, but the tail is extracted from the given index (by default i=1 as in List.tl) *)

 let rec tail ?(i:int=1) (l:'a list) = 
  if (i=0) then l else tail ~i:(i-1) (List.tl l)
 ;; 

 
 (**

Set operations

*)


 
 (** Substract the second argument from the first *)

 let substract = fun u d -> let p=(fun y -> not (List.mem y d)) in (List.filter p u)
 ;;

 
 (** subset a b check if a is a subset of b, i.e. if all elements of a belong to b. *)

 let subset a b = List.for_all (fun x->(List.mem x b)) a
 ;;

 
 (** eqset a b check if a and b represent the same set of values. *)

 let eqset a b = (subset a b) && (subset b a)
 ;;

 
 (** Intersection of list: AvB=A\(A\B) . *)

 let intersection a b = substract a (substract a b)
 ;; 

 
 (** Shortcut for List.iter with arguments in the opposite order: before the list, then the action to perfom. *)

 let foreach l f = List.iter f l
 ;;

 
 (** Returns a list with no duplicates. For large lists we suggest to use Hashset.uniq instead. *)

 let rec uniq = function
  | []   -> []
  | x::r -> if (List.mem x r) then (uniq r) else x::(uniq r) 
 ;;

 
 (**
 ;;

 
 (** eqset a b check if a and b represent the same set of values. *)

 let eqset a b = (subset a b) && (subset b a)
 ;;

 
 (** Intersection of list: AvB=A\(A\B) . *)

 let intersection a b = substract a (substract a b)
 ;; 

 
 (** Shortcut for List.iter with arguments in the opposite order: before the list, then the action to perfom. *)

 let foreach l f = List.iter f l
 ;;

 
 (** Returns a list with no duplicates. For large lists we suggest to use Hashset.uniq instead. *)

 let rec uniq = function
  | []   -> []
  | x::r -> if (List.mem x r) then (uniq r) else x::(uniq r) 
 ;;

 
 (**
 ;;

 
 (** eqset a b check if a and b represent the same set of values. *)

 let eqset a b = (subset a b) && (subset b a)
 ;;

 
 (** Intersection of list: AvB=A\(A\B) . *)

 let intersection a b = substract a (substract a b)
 ;; 

 
 (** Shortcut for List.iter with arguments in the opposite order: before the list, then the action to perfom. *)

 let foreach l f = List.iter f l
 ;;

 
 (** Returns a list with no duplicates. For large lists we suggest to use Hashset.uniq instead. *)

 let rec uniq = function
  | []   -> []
  | x::r -> if (List.mem x r) then (uniq r) else x::(uniq r) 
 ;;

 
 (**
 ;;

 
 (** eqset a b check if a and b represent the same set of values. *)

 let eqset a b = (subset a b) && (subset b a)
 ;;

 
 (** Intersection of list: AvB=A\(A\B) . *)

 let intersection a b = substract a (substract a b)
 ;; 

 
 (** Shortcut for List.iter with arguments in the opposite order: before the list, then the action to perfom. *)

 let foreach l f = List.iter f l
 ;;

 
 (** Returns a list with no duplicates. For large lists we suggest to use Hashset.uniq instead. *)

 let rec uniq = function
  | []   -> []
  | x::r -> if (List.mem x r) then (uniq r) else x::(uniq r) 
 ;;

 
 (**
 ;;

 
 (** eqset a b check if a and b represent the same set of values. *)

 let eqset a b = (subset a b) && (subset b a)
 ;;

 
 (** Intersection of list: AvB=A\(A\B) . *)

 let intersection a b = substract a (substract a b)
 ;; 

 
 (** Shortcut for List.iter with arguments in the opposite order: before the list, then the action to perfom. *)

 let foreach l f = List.iter f l
 ;;

 
 (** Returns a list with no duplicates. For large lists we suggest to use Hashset.uniq instead. *)

 let rec uniq = function
  | []   -> []
  | x::r -> if (List.mem x r) then (uniq r) else x::(uniq r) 
 ;;

 
 (**
 ;;

 
 (** eqset a b check if a and b represent the same set of values. *)

 let eqset a b = (subset a b) && (subset b a)
 ;;

 
 (** Intersection of list: AvB=A\(A\B) . *)

 let intersection a b = substract a (substract a b)
 ;; 

 
 (** Shortcut for List.iter with arguments in the opposite order: before the list, then the action to perfom. *)

 let foreach l f = List.iter f l
 ;;

 
 (** Returns a list with no duplicates. For large lists we suggest to use Hashset.uniq instead. *)

 let rec uniq = function
  | []   -> []
  | x::r -> if (List.mem x r) then (uniq r) else x::(uniq r) 
 ;;

 
 (**
 ;;

 
 (** eqset a b check if a and b represent the same set of values. *)

 let eqset a b = (subset a b) && (subset b a)
 ;;

 
 (** Intersection of list: AvB=A\(A\B) . *)

 let intersection a b = substract a (substract a b)
 ;; 

 
 (** Shortcut for List.iter with arguments in the opposite order: before the list, then the action to perfom. *)

 let foreach l f = List.iter f l
 ;;

 
 (** Returns a list with no duplicates. For large lists we suggest to use Hashset.uniq instead. *)

 let rec uniq = function
  | []   -> []
  | x::r -> if (List.mem x r) then (uniq r) else x::(uniq r) 
 ;;

 
 (**
 ;;

 
 (** eqset a b check if a and b represent the same set of values. *)

 let eqset a b = (subset a b) && (subset b a)
 ;;

 
 (** Intersection of list: AvB=A\(A\B) . *)

 let intersection a b = substract a (substract a b)
 ;; 

 
 (** Shortcut for List.iter with arguments in the opposite order: before the list, then the action to perfom. *)

 let foreach l f = List.iter f l
 ;;

 
 (** Returns a list with no duplicates. For large lists we suggest to use Hashset.uniq instead. *)

 let rec uniq = function
  | []   -> []
  | x::r -> if (List.mem x r) then (uniq r) else x::(uniq r) 
 ;;

 
 (**
 ;;

 
 (** eqset a b check if a and b represent the same set of values. *)

 let eqset a b = (subset a b) && (subset b a)
 ;;

 
 (** Intersection of list: AvB=A\(A\B) . *)

 let intersection a b = substract a (substract a b)
 ;; 

 
 (** Shortcut for List.iter with arguments in the opposite order: before the list, then the action to perfom. *)