anchor.diff:  exception EnumMatchIncomplete of bool * (string * bool) option * range
   
   type ActionOnFailure = 
  -  | ThrowIncompleteMatchException 
  -  | IgnoreWithWarning 
  -  | Throw 
  -  | Rethrow 
  -  | FailFilter
  +    | ThrowIncompleteMatchException 
  +    | IgnoreWithWarning 
  +    | Throw 
  +    | Rethrow 
  +    | FailFilter
   
   [<NoEquality; NoComparison>]
   /// Represents type-checked patterns
   type Pattern =
  -  | TPat_const of Const * range
  -  | TPat_wild of range  (* note = TPat_disjs([],m), but we haven't yet removed that duplication *)
  -  | TPat_as of  Pattern * PatternValBinding * range (* note: can be replaced by TPat_var, i.e. equals TPat_conjs([TPat_var; pat]) *)
  -  | TPat_disjs of  Pattern list * range
  -  | TPat_conjs of  Pattern list * range
  -  | TPat_query of (Expr * TType list * (ValRef * TypeInst) option * int * ActivePatternInfo) * Pattern * range
  -  | TPat_unioncase of UnionCaseRef * TypeInst * Pattern list * range
  -  | TPat_exnconstr of TyconRef * Pattern list * range
  -  | TPat_tuple of  TupInfo * Pattern list * TType list * range
  -  | TPat_array of  Pattern list * TType * range
  -  | TPat_recd of TyconRef * TypeInst * Pattern list * range
  -  | TPat_range of char * char * range
  -  | TPat_null of range
  -  | TPat_isinst of TType * TType * PatternValBinding option * range
  -  member this.Range =
  -    match this with
  -    |   TPat_const(_,m) -> m
  -    |   TPat_wild m -> m
  -    |   TPat_as(_,_,m) -> m
  -    |   TPat_disjs(_,m) -> m
  -    |   TPat_conjs(_,m) -> m
  -    |   TPat_query(_,_,m) -> m
  -    |   TPat_unioncase(_,_,_,m) -> m
  -    |   TPat_exnconstr(_,_,m) -> m
  -    |   TPat_tuple(_,_,_,m) -> m
  -    |   TPat_array(_,_,m) -> m
  -    |   TPat_recd(_,_,_,m) -> m
  -    |   TPat_range(_,_,m) -> m
  -    |   TPat_null(m) -> m
  -    |   TPat_isinst(_,_,_,m) -> m
  +    | TPat_const of Const * range
  +    | TPat_wild of range  (* note = TPat_disjs([],m), but we haven't yet removed that duplication *)
  +    | TPat_as of  Pattern * PatternValBinding * range (* note: can be replaced by TPat_var, i.e. equals TPat_conjs([TPat_var; pat]) *)
  +    | TPat_disjs of  Pattern list * range
  +    | TPat_conjs of  Pattern list * range
  +    | TPat_query of (Expr * TType list * (ValRef * TypeInst) option * int * ActivePatternInfo) * Pattern * range
  +    | TPat_unioncase of UnionCaseRef * TypeInst * Pattern list * range
  +    | TPat_exnconstr of TyconRef * Pattern list * range
  +    | TPat_tuple of  TupInfo * Pattern list * TType list * range
  +    | TPat_array of  Pattern list * TType * range
  +    | TPat_recd of TyconRef * TypeInst * Pattern list * range
  +    | TPat_range of char * char * range
  +    | TPat_null of range
  +    | TPat_isinst of TType * TType * PatternValBinding option * range
  +    member this.Range =
  +        match this with
  +        |   TPat_const(_,m) -> m
  +        |   TPat_wild m -> m
  +        |   TPat_as(_,_,m) -> m
  +        |   TPat_disjs(_,m) -> m
  +        |   TPat_conjs(_,m) -> m
  +        |   TPat_query(_,_,m) -> m
  +        |   TPat_unioncase(_,_,_,m) -> m
  +        |   TPat_exnconstr(_,_,m) -> m
  +        |   TPat_tuple(_,_,_,m) -> m
  +        |   TPat_array(_,_,m) -> m
  +        |   TPat_recd(_,_,_,m) -> m
  +        |   TPat_range(_,_,m) -> m
  +        |   TPat_null(m) -> m
  +        |   TPat_isinst(_,_,_,m) -> m
   
   and PatternValBinding = PBind of Val * TypeScheme
   
  
positive.code:                         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.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 -> 
          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(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
         
  //---------------------------------------------------------------------------
  // Basic problem specification
  
negative.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 
  