anchor.diff:                          Expr.Op(TOp.ValFieldGet v, [ty], [], m), false
                   | _ -> Expr.Const(c,m,ty), false
               
  -        | (DecisionTreeTest.UnionCase (ucref1,tinst) :: rest) -> 
  -             let ucrefs = ucref1 :: List.choose (function DecisionTreeTest.UnionCase(ucref,_) -> Some ucref | _ -> None) rest
  -             let tcref = ucref1.TyconRef
  -             (* Choose the first ucref based on ordering of names *)
  -             let others = 
  -                 tcref.UnionCasesAsRefList 
  -                 |> List.filter (fun ucref -> not (List.exists (g.unionCaseRefEq ucref) ucrefs)) 
  -                 |> List.sortBy (fun ucref -> ucref.CaseName)
  -             match others with 
  -             | [] -> raise CannotRefute
  -             | ucref2 :: _ -> 
  -               let flds = ucref2 |> actualTysOfUnionCaseFields (mkTyconRefInst tcref tinst) |> mkUnknowns
  -               Expr.Op(TOp.UnionCase(ucref2),tinst, flds,m), false
  +        | (DecisionTreeTest.UnionCase (ucref1,tinst) :: rest) ->
  +            let ucrefs = ucref1 :: List.choose (function DecisionTreeTest.UnionCase(ucref,_) -> Some ucref | _ -> None) rest
  +            let tcref = ucref1.TyconRef
  +            (* Choose the first ucref based on ordering of names *)
  +            let others =
  +                tcref.UnionCasesAsRefList
  +                |> List.filter (fun ucref -> not (List.exists (g.unionCaseRefEq ucref) ucrefs))
  +                |> List.sortBy (fun ucref -> ucref.CaseName)
  +            match others with
  +            | [] -> raise CannotRefute
  +            | ucref2 :: _ ->
  +                let flds = ucref2 |> actualTysOfUnionCaseFields (mkTyconRefInst tcref tinst) |> mkUnknowns
  +                Expr.Op(TOp.UnionCase(ucref2),tinst, flds,m), false
                  
  -        | [DecisionTreeTest.ArrayLength (n,ty)] -> 
  -             Expr.Op(TOp.Array,[ty], mkUnknowns (List.replicate (n+1) ty) ,m), false
  +        | [DecisionTreeTest.ArrayLength (n,ty)] ->
  +            Expr.Op(TOp.Array,[ty], mkUnknowns (List.replicate (n+1) ty) ,m), false
                
           | _ -> 
               raise CannotRefute
       go path tm
   
   let rec CombineRefutations g r1 r2 =
  -   match r1,r2 with
  -   | Expr.Val(vref,_,_), other | other, Expr.Val(vref,_,_) when vref.LogicalName = "_" -> other 
  -   | Expr.Val(vref,_,_), other | other, Expr.Val(vref,_,_) when vref.LogicalName = notNullText -> other 
  -   | Expr.Val(vref,_,_), other | other, Expr.Val(vref,_,_) when vref.LogicalName = otherSubtypeText -> other 
  -
  -   | Expr.Op((TOp.ExnConstr(ecref1) as op1), tinst1,flds1,m1), Expr.Op(TOp.ExnConstr(ecref2), _,flds2,_) when tyconRefEq g ecref1 ecref2 -> 
  +    match r1,r2 with
  +    | Expr.Val(vref,_,_), other | other, Expr.Val(vref,_,_) when vref.LogicalName = "_" -> other
  +    | Expr.Val(vref,_,_), other | other, Expr.Val(vref,_,_) when vref.LogicalName = notNullText -> other
  +    | Expr.Val(vref,_,_), other | other, Expr.Val(vref,_,_) when vref.LogicalName = otherSubtypeText -> other
  +
  +    | Expr.Op((TOp.ExnConstr(ecref1) as op1), tinst1,flds1,m1), Expr.Op(TOp.ExnConstr(ecref2), _,flds2,_) when tyconRefEq g ecref1 ecref2 -> 
           Expr.Op(op1, tinst1,List.map2 (CombineRefutations g) flds1 flds2,m1)
   
  -   | Expr.Op((TOp.UnionCase(ucref1) as op1), tinst1,flds1,m1), 
  -     Expr.Op(TOp.UnionCase(ucref2), _,flds2,_)  -> 
  -       if g.unionCaseRefEq ucref1 ucref2 then 
  -           Expr.Op(op1, tinst1,List.map2 (CombineRefutations g) flds1 flds2,m1)
  -       (* Choose the greater of the two ucrefs based on name ordering *)
  -       elif ucref1.CaseName < ucref2.CaseName then 
  -           r2
  -       else 
  -           r1
  +    | Expr.Op((TOp.UnionCase(ucref1) as op1), tinst1,flds1,m1), Expr.Op(TOp.UnionCase(ucref2), _,flds2,_) ->
  +        if g.unionCaseRefEq ucref1 ucref2 then
  +            Expr.Op(op1, tinst1,List.map2 (CombineRefutations g) flds1 flds2,m1)
  +        (* Choose the greater of the two ucrefs based on name ordering *)
  +        elif ucref1.CaseName < ucref2.CaseName then
  +            r2
  +        else 
  +            r1
           
  -   | Expr.Op(op1, tinst1,flds1,m1), Expr.Op(_, _,flds2,_) -> 
  +    | Expr.Op(op1, tinst1,flds1,m1), Expr.Op(_, _,flds2,_) ->
           Expr.Op(op1, tinst1,List.map2 (CombineRefutations g) flds1 flds2,m1)
           
  -   | Expr.Const(c1, m1, ty1), Expr.Const(c2,_,_) -> 
  -       let c12 = 
  -
  -           // Make sure longer strings are greater, not the case in the default ordinal comparison
  -           // This is needed because the individual counter examples make longer strings
  -           let MaxStrings s1 s2 = 
  -               let c = compare (String.length s1) (String.length s2)
  -               if c < 0 then s2 
  -               elif c > 0 then s1 
  -               elif s1 < s2 then s2 
  -               else s1
  -               
  -           match c1,c2 with 
  -           | Const.String(s1), Const.String(s2) -> Const.String(MaxStrings s1 s2)
  -           | Const.Decimal(s1), Const.Decimal(s2) -> Const.Decimal(max s1 s2)
  -           | _ -> max c1 c2 
  -           
  -       (* REVIEW: we could return a better enumeration literal field here if a field matches one of the enumeration cases *)
  -       Expr.Const(c12, m1, ty1)
  -
  -   | _ -> r1 
  -
  -let ShowCounterExample g denv m refuted = 
  -   try
  -      let refutations = refuted |> List.collect (function RefutedWhenClause -> [] | (RefutedInvestigation(path,discrim)) -> [RefuteDiscrimSet g m path discrim])
  -      let counterExample, enumCoversKnown = 
  -          match refutations with 
  -          | [] -> raise CannotRefute
  -          | (r, eck) :: t -> 
  -              if verbose then dprintf "r = %s (enumCoversKnownValue = %b)\n" (Layout.showL (exprL r)) eck
  -              List.fold (fun (rAcc, eckAcc) (r, eck) ->
  -                  CombineRefutations g rAcc r, eckAcc || eck) (r, eck) t
  -      let text = Layout.showL (NicePrint.dataExprL denv counterExample)
  -      let failingWhenClause = refuted |> List.exists (function RefutedWhenClause -> true | _ -> false)
  -      Some(text,failingWhenClause,enumCoversKnown)
  -      
  -    with 
  -        | CannotRefute ->    
  -          None 
  -        | e -> 
  -          warning(InternalError(sprintf "<failure during counter example generation: %s>" (e.ToString()),m))
  -          None
  +    | Expr.Const(c1, m1, ty1), Expr.Const(c2,_,_) ->
  +        let c12 =
  +
  +            // Make sure longer strings are greater, not the case in the default ordinal comparison
  +            // This is needed because the individual counter examples make longer strings
  +            let MaxStrings s1 s2 =
  +                let c = compare (String.length s1) (String.length s2)
  +                if c < 0 then s2
  +                elif c > 0 then s1
  +                elif s1 < s2 then s2
  +                else s1
  +                
  +            match c1,c2 with
  +            | Const.String(s1), Const.String(s2) -> Const.String(MaxStrings s1 s2)
  +            | Const.Decimal(s1), Const.Decimal(s2) -> Const.Decimal(max s1 s2)
  +            | _ -> max c1 c2
  +        
  +        Expr.Const(c12, m1, ty1)
  +
  +    | _ -> r1
  +
  +let ShowCounterExample g denv m refuted =
  +    try
  +        let refutations = refuted |> List.collect (function RefutedWhenClause -> [] | (RefutedInvestigation(path,discrim)) -> [RefuteDiscrimSet g m path discrim])
  +        let counterExample, enumCoversKnown =
  +            match refutations with
  +            | [] -> raise CannotRefute
  +            | (r, eck) :: t ->
  +                if verbose then dprintf "r = %s (enumCoversKnownValue = %b)\n" (Layout.showL (exprL r)) eck
  +                List.fold (fun (rAcc, eckAcc) (r, eck) ->
  +                    CombineRefutations g rAcc r, eckAcc || eck) (r, eck) t
  +        let text = Layout.showL (NicePrint.dataExprL denv counterExample)
  +        let failingWhenClause = refuted |> List.exists (function RefutedWhenClause -> true | _ -> false)
  +        Some(text,failingWhenClause,enumCoversKnown)
  +    
  +    with
  +    | CannotRefute ->
  +        None
  +    | e ->
  +        warning(InternalError(sprintf "<failure during counter example generation: %s>" (e.ToString()),m))
  +        None
          
   //---------------------------------------------------------------------------
   // Basic problem specification
  
positive.code:             let tyargs = 
                  let someSolved = ref false
                  let freezeVar gtp = 
                       if isBeingGeneralized gtp tyscheme then 
                           mkTyparTy gtp 
                       else 
                           someSolved := true
                           TypeRelations.ChooseTyparSolution g amap gtp
  
                  let solutions = List.map freezeVar gtps
                  if !someSolved then 
  
negative.code:         List.map fst flds, List.fold (fun acc (_, eCoversVals) -> eCoversVals || acc) false flds
      and mkUnknowns tys = List.map (fun x -> mkUnknown x) tys
  
      let tm ty =
          match discrims with
          | [DecisionTreeTest.IsNull] ->
              snd(mkCompGenLocal m notNullText ty), false
          | [DecisionTreeTest.IsInst (_,_)] ->
              snd(mkCompGenLocal m otherSubtypeText ty), false
          | (DecisionTreeTest.Const c :: rest) ->
              let consts = Set.ofList (c :: List.choose (function DecisionTreeTest.Const(c) -> Some c | _ -> None) rest)
              let c' =
                  Seq.tryFind (fun c -> not (consts.Contains(c)))
                     (match c with
                      | Const.Bool _ -> [ true; false ] |> List.toSeq |> Seq.map (fun v -> Const.Bool(v))
                      | Const.SByte _ ->  Seq.append (seq { 0y .. System.SByte.MaxValue }) (seq { System.SByte.MinValue .. 0y })|> Seq.map (fun v -> Const.SByte(v))
                      | Const.Int16 _ -> Seq.append (seq { 0s .. System.Int16.MaxValue }) (seq { System.Int16.MinValue .. 0s }) |> Seq.map (fun v -> Const.Int16(v))
                      | Const.Int32 _ ->  Seq.append (seq { 0 .. System.Int32.MaxValue }) (seq { System.Int32.MinValue .. 0 })|> Seq.map (fun v -> Const.Int32(v))
                      | Const.Int64 _ ->  Seq.append (seq { 0L .. System.Int64.MaxValue }) (seq { System.Int64.MinValue .. 0L })|> Seq.map (fun v -> Const.Int64(v))
                      | Const.IntPtr _ ->  Seq.append (seq { 0L .. System.Int64.MaxValue }) (seq { System.Int64.MinValue .. 0L })|> Seq.map (fun v -> Const.IntPtr(v))
                      | Const.Byte _ -> seq { 0uy .. System.Byte.MaxValue } |> Seq.map (fun v -> Const.Byte(v))
                      | Const.UInt16 _ -> seq { 0us .. System.UInt16.MaxValue } |> Seq.map (fun v -> Const.UInt16(v))
                      | Const.UInt32 _ -> seq { 0u .. System.UInt32.MaxValue } |> Seq.map (fun v -> Const.UInt32(v))
                      | Const.UInt64 _ -> seq { 0UL .. System.UInt64.MaxValue } |> Seq.map (fun v -> Const.UInt64(v))
                      | Const.UIntPtr _ -> seq { 0UL .. System.UInt64.MaxValue } |> Seq.map (fun v -> Const.UIntPtr(v))
                      | Const.Double _ -> seq { 0 .. System.Int32.MaxValue } |> Seq.map (fun v -> Const.Double(float v))
                      | Const.Single _ -> seq { 0 .. System.Int32.MaxValue } |> Seq.map (fun v -> Const.Single(float32 v))
                      | Const.Char _ -> seq { 32us .. System.UInt16.MaxValue } |> Seq.map (fun v -> Const.Char(char v))
                      | Const.String _ -> seq { 1 .. System.Int32.MaxValue } |> Seq.map (fun v -> Const.String(new System.String('a',v)))
                      | Const.Decimal _ -> seq { 1 .. System.Int32.MaxValue } |> Seq.map (fun v -> Const.Decimal(decimal v))
                      | _ -> 
                          raise CannotRefute)
              
              match c' with 
              | None -> raise CannotRefute
  