anchor.diff:          r.AddOutput m
           m
   
  +    /// <summary>
  +    /// adaptively checks if the set contains the given element
  +    /// </summary>
       let contains (elem : 'a) (set : aset<'a>) =
           set |> toMod |> Mod.map (fun s -> s.Contains elem)
   
  +    /// <summary>
  +    /// adaptively checks if the set contains all given elements
  +    /// </summary>
       let containsAll (elems : #seq<'a>) (set : aset<'a>) =
           set |> toMod |> Mod.map (fun s -> elems |> Seq.forall (fun e -> s.Contains e))
   
  +    /// <summary>
  +    /// adaptively checks if the set contains any of the given elements
  +    /// </summary>
       let containsAny (elems : #seq<'a>) (set : aset<'a>) =
           set |> toMod |> Mod.map (fun s -> elems |> Seq.exists (fun e -> s.Contains e))
   
  -
  +    /// <summary>
  +    /// applies the given function to all elements in the set
  +    /// and returns a new set containing the respective results.
  +    /// NOTE: duplicates are handled correctly here which means
  +    ///       that the function may be non-injective
  +    /// </summary>
       let map (f : 'a -> 'b) (set : aset<'a>) = 
           let scope = Ag.getContext()
           AdaptiveSet(fun () -> set.GetReader() |> map scope f) :> aset<'b>
   
  +    /// <summary>
  +    /// applies the given function to a cell and adaptively
  +    /// returns the resulting set.
  +    /// </summary>
       let bind (f : 'a -> aset<'b>) (m : IMod<'a>) =
           let scope = Ag.getContext()
           AdaptiveSet(fun () -> m |> bind scope (fun v -> (f v).GetReader())) :> aset<'b>
   
  +    /// <summary>
  +    /// applies the given function to both cells and adaptively
  +    /// returns the resulting set.
  +    /// </summary>
       let bind2 (f : 'a -> 'b -> aset<'c>) (ma : IMod<'a>) (mb : IMod<'b>) =
           let scope = Ag.getContext()
           AdaptiveSet(fun () -> bind2 scope (fun a b -> (f a b).GetReader()) ma mb) :> aset<'c>
   
  -
  +    /// <summary>
  +    /// applies the given function to all elements in the set
  +    /// and unions all output-sets.
  +    /// NOTE: duplicates are handled correctly here meaning that
  +    ///       the given function may return overlapping sets.
  +    /// </summary>
       let collect (f : 'a -> aset<'b>) (set : aset<'a>) = 
           let scope = Ag.getContext()
           AdaptiveSet(fun () -> set.GetReader() |> collect scope (fun v -> (f v).GetReader())) :> aset<'b>
   
  +    /// <summary>
  +    /// applies the given function to all elements in the set
  +    /// and returns a set containing all the elements that were Some(v)
  +    /// NOTE: duplicates are handled correctly here which means
  +    ///       that the function may be non-injective
  +    /// </summary>
       let choose (f : 'a -> Option<'b>) (set : aset<'a>) =
           let scope = Ag.getContext()
           AdaptiveSet(fun () -> set.GetReader() |> choose scope f) :> aset<'b>
   
  +    /// <summary>
  +    /// filters the elements in the set using the given predicate
  +    /// </summary>
       let filter (f : 'a -> bool) (set : aset<'a>) =
           choose (fun v -> if f v then Some v else None) set
   
  +
  +    let union (set : aset<aset<'a>>) =
  +        collect id set
  +
  +    let union' (set : seq<aset<'a>>) =
  +        union (ConstantSet set)
  +
       let concat (set : aset<aset<'a>>) =
           collect id set
   
  
positive.code:         let scope = Ag.getContext()
          fun v -> Ag.useScope scope (fun () -> f v)
  
      let empty<'a> : aset<'a> =
          EmptySetImpl<'a>.Instance
  
      let single (v : 'a) =
          ConstantSet [v] :> aset<_>
  
      let ofSeq (s : seq<'a>) =
          ConstantSet(s) :> aset<_>
  
      let ofList (l : list<'a>) =
          ConstantSet(l) :> aset<_>
  
      let ofArray (a : 'a[]) =
          ConstantSet(a) :> aset<_>
  
      let toList (set : aset<'a>) =
          use r = set.GetReader()
          r.GetDelta() |> ignore
          r.Content |> Seq.toList
  
      let toSeq (set : aset<'a>) =
          let l = toList set
          l :> seq<_>
  
      let toArray (set : aset<'a>) =
          use r = set.GetReader()
          r.GetDelta() |> ignore
          r.Content |> Seq.toArray
  
      let ofMod (m : IMod<'a>) =
          AdaptiveSet(fun () -> ofMod m) :> aset<_>
  
      let toMod (s : aset<'a>) =
          let r = s.GetReader()
          let c = r.Content :> IVersionedSet<_>
  
negative.code:     let foldSemiGroup (add : 'a -> 'a -> 'a) (zero : 'a) (s : aset<'a>) : IMod<'a> =
          let r = s.GetReader()
          let sum = ref zero
  
          let rec processDeltas (deltas : list<Delta<'a>>) =
              match deltas with
                  | Add v :: deltas ->
                      sum := add !sum v
                      processDeltas deltas
                  | Rem v :: deltas ->
                      false
                  | [] ->
                      true
  
          let res =
              Mod.custom (fun () ->
                  let mutable rem = false
                  let delta = r.GetDelta()
  
                  if not <| processDeltas delta then
                      sum := r.Content |> Seq.fold add zero
  
                  !sum
  