anchor.diff:       | o ->
          let t = o.GetType ()
          if hasInferenceRules t
  -          && HashEqMap.tryFind t ruleSet.rules |> Option.isNone
  -       then let rules = HashEqMap.add t (collectRules o |> Seq.toArray) ruleSet.rules
  -            {rules = rules
  -             tree = lazy (rules
  -                          |> HashEqMap.toSeq
  -                          |> Seq.collect (fun (_, rules) ->
  -                             rules
  -                             |> Seq.map (fun rule -> (rule.ReturnType, rule)))
  -                          |> TyTree.build
  -                          |> force)}
  +          && HashEqSet.contains t ruleSet.rules |> not
  +       then let rules = HashEqSet.add t ruleSet.rules
  +            if ruleSet.env.ContainsKey t |> not then
  +              ruleSet.env.Add (t, collectRules o |> Seq.toArray)
  +            {ruleSet with
  +              rules = rules
  +              tree = lazy (rules
  +                           |> HashEqSet.toSeq
  +                           |> Seq.collect (fun t ->
  +                              ruleSet.env.[t]
  +                              |> Seq.map (fun rule -> (rule.ReturnType, rule)))
  +                           |> TyTree.build
  +                           |> force)}
          else ruleSet
   
     let rulesFor (ruleSet: RuleSet) (desiredTy: Ty<_>) = seq {
  
positive.code:     o.GetType ()
      |> collectRules
  
    let empty = {rules = HashEqMap.empty; tree = TyTree.build []}
  
    let maybeAddRules (o: obj) ruleSet =
      match o with
  
negative.code:   let mutable private counter = 0L
  
    let newMapper () =
      let v2w = Dictionary<_, _> ()
      fun v ->
        match v2w.TryGetValue v with
         | (true, w) -> w
  