anchor.diff:         if hasInferenceRules t
             && 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)}
  +            if ruleSet.rulesCache.ContainsKey t |> not then
  +              ruleSet.rulesCache.Add (t, collectRules o |> Seq.toArray)
  +            let tree =
  +              match ruleSet.treesCache.TryGetValue rules with
  +               | (true, tree) -> tree
  +               | (false, _) ->
  +                 let tree =
  +                   lazy (rules
  +                         |> HashEqSet.toSeq
  +                         |> Seq.collect (fun t ->
  +                            ruleSet.rulesCache.[t]
  +                            |> Seq.map (fun rule -> (rule.ReturnType, rule)))
  +                         |> TyTree.build
  +                         |> force)
  +                 ruleSet.treesCache.Add (rules, tree)
  +                 tree
  +            {ruleSet with rules = rules; tree = tree}
          else ruleSet
   
     let rulesFor (ruleSet: RuleSet) (desiredTy: Ty<_>) = seq {
  
positive.code: 
  module RuleSet =
    type RuleSet = {
      env: Dictionary<Type, array<Rule<Type>>>
      rules: HashEqSet<Type>
      tree: TyTree<Rule<Type>>
    }
  
negative.code:   let tryGenerate (rules: obj) : option<'a> =
      let desTy = typeof<'a> |> Ty.ofType |> mapVars (Fresh.newMapper ())
      let rules =
        RuleSet.newEmpty ()
        |> RuleSet.maybeAddRules rules
      seq {1 .. Int32.MaxValue}
      |> Seq.tryPick (fun limit ->
  