@@ -22,45 +22,45 @@ exception RuleNeverMatched of range
2222exception EnumMatchIncompleteof bool * ( string * bool ) option * range
2323
2424type ActionOnFailure =
25- | ThrowIncompleteMatchException
26- | IgnoreWithWarning
27- | Throw
28- | Rethrow
29- | FailFilter
25+ | ThrowIncompleteMatchException
26+ | IgnoreWithWarning
27+ | Throw
28+ | Rethrow
29+ | FailFilter
3030
3131[<NoEquality; NoComparison>]
3232/// Represents type-checked patterns
3333type Pattern =
34- | TPat_ constof Const * range
35- | TPat_ wildof range (* note = TPat_disjs([],m), but we haven't yet removed that duplication*)
36- | TPat_ asof Pattern * PatternValBinding * range (* note: can be replaced by TPat_var, i.e. equals TPat_conjs([TPat_var; pat])*)
37- | TPat_ disjsof Pattern list * range
38- | TPat_ conjsof Pattern list * range
39- | TPat_ queryof ( Expr * TType list * ( ValRef * TypeInst ) option * int * ActivePatternInfo ) * Pattern * range
40- | TPat_ unioncaseof UnionCaseRef * TypeInst * Pattern list * range
41- | TPat_ exnconstrof TyconRef * Pattern list * range
42- | TPat_ tupleof TupInfo * Pattern list * TType list * range
43- | TPat_ arrayof Pattern list * TType * range
44- | TPat_ recdof TyconRef * TypeInst * Pattern list * range
45- | TPat_ rangeof char * char * range
46- | TPat_ nullof range
47- | TPat_ isinstof TType * TType * PatternValBinding option * range
48- member this.Range =
49- match thiswith
50- | TPat_ const(_, m) -> m
51- | TPat_ wild m-> m
52- | TPat_ as(_,_, m) -> m
53- | TPat_ disjs(_, m) -> m
54- | TPat_ conjs(_, m) -> m
55- | TPat_ query(_,_, m) -> m
56- | TPat_ unioncase(_,_,_, m) -> m
57- | TPat_ exnconstr(_,_, m) -> m
58- | TPat_ tuple(_,_,_, m) -> m
59- | TPat_ array(_,_, m) -> m
60- | TPat_ recd(_,_,_, m) -> m
61- | TPat_ range(_,_, m) -> m
62- | TPat_ null( m) -> m
63- | TPat_ isinst(_,_,_, m) -> m
34+ | TPat_ constof Const * range
35+ | TPat_ wildof range (* note = TPat_disjs([],m), but we haven't yet removed that duplication*)
36+ | TPat_ asof Pattern * PatternValBinding * range (* note: can be replaced by TPat_var, i.e. equals TPat_conjs([TPat_var; pat])*)
37+ | TPat_ disjsof Pattern list * range
38+ | TPat_ conjsof Pattern list * range
39+ | TPat_ queryof ( Expr * TType list * ( ValRef * TypeInst ) option * int * ActivePatternInfo ) * Pattern * range
40+ | TPat_ unioncaseof UnionCaseRef * TypeInst * Pattern list * range
41+ | TPat_ exnconstrof TyconRef * Pattern list * range
42+ | TPat_ tupleof TupInfo * Pattern list * TType list * range
43+ | TPat_ arrayof Pattern list * TType * range
44+ | TPat_ recdof TyconRef * TypeInst * Pattern list * range
45+ | TPat_ rangeof char * char * range
46+ | TPat_ nullof range
47+ | TPat_ isinstof TType * TType * PatternValBinding option * range
48+ member this.Range =
49+ match thiswith
50+ | TPat_ const(_, m) -> m
51+ | TPat_ wild m-> m
52+ | TPat_ as(_,_, m) -> m
53+ | TPat_ disjs(_, m) -> m
54+ | TPat_ conjs(_, m) -> m
55+ | TPat_ query(_,_, m) -> m
56+ | TPat_ unioncase(_,_,_, m) -> m
57+ | TPat_ exnconstr(_,_, m) -> m
58+ | TPat_ tuple(_,_,_, m) -> m
59+ | TPat_ array(_,_, m) -> m
60+ | TPat_ recd(_,_,_, m) -> m
61+ | TPat_ range(_,_, m) -> m
62+ | TPat_ null( m) -> m
63+ | TPat_ isinst(_,_,_, m) -> m
6464
6565and PatternValBinding = PBindof Val * TypeScheme
6666
@@ -105,11 +105,11 @@ let BindSubExprOfInput g amap gtps (PBind(v,tyscheme)) m (SubExpr(accessf,(ve2,v
105105let tyargs =
106106let someSolved = reffalse
107107let freezeVar gtp =
108- if isBeingGeneralized gtp tyschemethen
109- mkTyparTy gtp
110- else
111- someSolved:= true
112- TypeRelations.ChooseTyparSolution g amap gtp
108+ if isBeingGeneralized gtp tyschemethen
109+ mkTyparTy gtp
110+ else
111+ someSolved:= true
112+ TypeRelations.ChooseTyparSolution g amap gtp
113113
114114let solutions = List.map freezeVar gtps
115115if ! someSolvedthen
@@ -176,25 +176,25 @@ let RefuteDiscrimSet g m path discrims =
176176match pathwith
177177| PathQuery_ -> raise CannotRefute
178178| PathConj( p,_ j) ->
179- go p tm
179+ go p tm
180180| PathTuple( p, tys, j) ->
181- let k , eCoversVals = mkOneKnown tm j tys
182- go p( fun _ -> mkRefTupled g m k tys, eCoversVals)
181+ let k , eCoversVals = mkOneKnown tm j tys
182+ go p( fun _ -> mkRefTupled g m k tys, eCoversVals)
183183| PathRecd( p, tcref, tinst, j) ->
184- let flds , eCoversVals = tcref|> actualTysOfInstanceRecdFields( mkTyconRefInst tcref tinst) |> mkOneKnown tm j
185- go p( fun _ -> Expr.Op( TOp.Recd( RecdExpr, tcref), tinst, flds, m), eCoversVals)
184+ let flds , eCoversVals = tcref|> actualTysOfInstanceRecdFields( mkTyconRefInst tcref tinst) |> mkOneKnown tm j
185+ go p( fun _ -> Expr.Op( TOp.Recd( RecdExpr, tcref), tinst, flds, m), eCoversVals)
186186
187187| PathUnionConstr( p, ucref, tinst, j) ->
188- let flds , eCoversVals = ucref|> actualTysOfUnionCaseFields( mkTyconRefInst ucref.TyconRef tinst)|> mkOneKnown tm j
189- go p( fun _ -> Expr.Op( TOp.UnionCase( ucref), tinst, flds, m), eCoversVals)
188+ let flds , eCoversVals = ucref|> actualTysOfUnionCaseFields( mkTyconRefInst ucref.TyconRef tinst)|> mkOneKnown tm j
189+ go p( fun _ -> Expr.Op( TOp.UnionCase( ucref), tinst, flds, m), eCoversVals)
190190
191191| PathArray( p, ty, len, n) ->
192- let flds , eCoversVals = mkOneKnown tm n( List.replicate len ty)
193- go p( fun _ -> Expr.Op( TOp.Array,[ ty], flds, m), eCoversVals)
192+ let flds , eCoversVals = mkOneKnown tm n( List.replicate len ty)
193+ go p( fun _ -> Expr.Op( TOp.Array,[ ty], flds, m), eCoversVals)
194194
195195| PathExnConstr( p, ecref, n) ->
196- let flds , eCoversVals = ecref|> recdFieldTysOfExnDefRef|> mkOneKnown tm n
197- go p( fun _ -> Expr.Op( TOp.ExnConstr( ecref),[], flds, m), eCoversVals)
196+ let flds , eCoversVals = ecref|> recdFieldTysOfExnDefRef|> mkOneKnown tm n
197+ go p( fun _ -> Expr.Op( TOp.ExnConstr( ecref),[], flds, m), eCoversVals)
198198
199199| PathEmpty( ty) -> tm ty
200200
@@ -203,35 +203,35 @@ let RefuteDiscrimSet g m path discrims =
203203 List.map fst flds, List.fold( fun acc ( _ , eCoversVals ) -> eCoversVals|| acc) false flds
204204and mkUnknowns tys = List.map( fun x -> mkUnknown x) tys
205205
206- let tm ty =
207- match discrimswith
208- | [ DecisionTreeTest.IsNull] ->
206+ let tm ty =
207+ match discrimswith
208+ | [ DecisionTreeTest.IsNull] ->
209209 snd( mkCompGenLocal m notNullText ty), false
210- | [ DecisionTreeTest.IsInst(_,_)] ->
210+ | [ DecisionTreeTest.IsInst(_,_)] ->
211211 snd( mkCompGenLocal m otherSubtypeText ty), false
212- | ( DecisionTreeTest.Const c:: rest) ->
212+ | ( DecisionTreeTest.Const c:: rest) ->
213213let consts = Set.ofList( c:: List.choose( function DecisionTreeTest.Const( c) -> Some c| _ -> None) rest)
214- let c ' =
214+ let c ' =
215215 Seq.tryFind( fun c -> not ( consts.Contains( c)))
216- ( match cwith
217- | Const.Bool_ -> [ true ; false ] |> List.toSeq|> Seq.map( fun v -> Const.Bool( v))
218- | Const.SByte_ -> Seq.append( seq { 0 y.. System.SByte.MaxValue}) ( seq { System.SByte.MinValue.. 0 y})|> Seq.map( fun v -> Const.SByte( v))
219- | Const.Int16_ -> Seq.append( seq { 0 s.. System.Int16.MaxValue}) ( seq { System.Int16.MinValue.. 0 s}) |> Seq.map( fun v -> Const.Int16( v))
220- | Const.Int32_ -> Seq.append( seq { 0 .. System.Int32.MaxValue}) ( seq { System.Int32.MinValue.. 0 })|> Seq.map( fun v -> Const.Int32( v))
221- | Const.Int64_ -> Seq.append( seq { 0 L.. System.Int64.MaxValue}) ( seq { System.Int64.MinValue.. 0 L})|> Seq.map( fun v -> Const.Int64( v))
222- | Const.IntPtr_ -> Seq.append( seq { 0 L.. System.Int64.MaxValue}) ( seq { System.Int64.MinValue.. 0 L})|> Seq.map( fun v -> Const.IntPtr( v))
223- | Const.Byte_ -> seq { 0 uy.. System.Byte.MaxValue} |> Seq.map( fun v -> Const.Byte( v))
224- | Const.UInt16_ -> seq { 0 us.. System.UInt16.MaxValue} |> Seq.map( fun v -> Const.UInt16( v))
225- | Const.UInt32_ -> seq { 0 u.. System.UInt32.MaxValue} |> Seq.map( fun v -> Const.UInt32( v))
226- | Const.UInt64_ -> seq { 0 UL.. System.UInt64.MaxValue} |> Seq.map( fun v -> Const.UInt64( v))
227- | Const.UIntPtr_ -> seq { 0 UL.. System.UInt64.MaxValue} |> Seq.map( fun v -> Const.UIntPtr( v))
228- | Const.Double_ -> seq { 0 .. System.Int32.MaxValue} |> Seq.map( fun v -> Const.Double( float v))
229- | Const.Single_ -> seq { 0 .. System.Int32.MaxValue} |> Seq.map( fun v -> Const.Single( float32 v))
230- | Const.Char_ -> seq { 32 us.. System.UInt16.MaxValue} |> Seq.map( fun v -> Const.Char( char v))
231- | Const.String_ -> seq { 1 .. System.Int32.MaxValue} |> Seq.map( fun v -> Const.String( new System.String( 'a' , v)))
232- | Const.Decimal_ -> seq { 1 .. System.Int32.MaxValue} |> Seq.map( fun v -> Const.Decimal( decimal v))
233- | _ ->
234- raise CannotRefute)
216+ ( match cwith
217+ | Const.Bool_ -> [ true ; false ] |> List.toSeq|> Seq.map( fun v -> Const.Bool( v))
218+ | Const.SByte_ -> Seq.append( seq { 0 y.. System.SByte.MaxValue}) ( seq { System.SByte.MinValue.. 0 y})|> Seq.map( fun v -> Const.SByte( v))
219+ | Const.Int16_ -> Seq.append( seq { 0 s.. System.Int16.MaxValue}) ( seq { System.Int16.MinValue.. 0 s}) |> Seq.map( fun v -> Const.Int16( v))
220+ | Const.Int32_ -> Seq.append( seq { 0 .. System.Int32.MaxValue}) ( seq { System.Int32.MinValue.. 0 })|> Seq.map( fun v -> Const.Int32( v))
221+ | Const.Int64_ -> Seq.append( seq { 0 L.. System.Int64.MaxValue}) ( seq { System.Int64.MinValue.. 0 L})|> Seq.map( fun v -> Const.Int64( v))
222+ | Const.IntPtr_ -> Seq.append( seq { 0 L.. System.Int64.MaxValue}) ( seq { System.Int64.MinValue.. 0 L})|> Seq.map( fun v -> Const.IntPtr( v))
223+ | Const.Byte_ -> seq { 0 uy.. System.Byte.MaxValue} |> Seq.map( fun v -> Const.Byte( v))
224+ | Const.UInt16_ -> seq { 0 us.. System.UInt16.MaxValue} |> Seq.map( fun v -> Const.UInt16( v))
225+ | Const.UInt32_ -> seq { 0 u.. System.UInt32.MaxValue} |> Seq.map( fun v -> Const.UInt32( v))
226+ | Const.UInt64_ -> seq { 0 UL.. System.UInt64.MaxValue} |> Seq.map( fun v -> Const.UInt64( v))
227+ | Const.UIntPtr_ -> seq { 0 UL.. System.UInt64.MaxValue} |> Seq.map( fun v -> Const.UIntPtr( v))
228+ | Const.Double_ -> seq { 0 .. System.Int32.MaxValue} |> Seq.map( fun v -> Const.Double( float v))
229+ | Const.Single_ -> seq { 0 .. System.Int32.MaxValue} |> Seq.map( fun v -> Const.Single( float32 v))
230+ | Const.Char_ -> seq { 32 us.. System.UInt16.MaxValue} |> Seq.map( fun v -> Const.Char( char v))
231+ | Const.String_ -> seq { 1 .. System.Int32.MaxValue} |> Seq.map( fun v -> Const.String( new System.String( 'a' , v)))
232+ | Const.Decimal_ -> seq { 1 .. System.Int32.MaxValue} |> Seq.map( fun v -> Const.Decimal( decimal v))
233+ | _ ->
234+ raise CannotRefute)
235235
236236match c'with
237237| None-> raise CannotRefute
@@ -251,91 +251,89 @@ let RefuteDiscrimSet g m path discrims =
251251 Expr.Op( TOp.ValFieldGet v, [ ty], [], m), false
252252| _ -> Expr.Const( c, m, ty), false
253253
254- | ( DecisionTreeTest.UnionCase( ucref1, tinst) :: rest) ->
255- let ucrefs = ucref1:: List.choose( function DecisionTreeTest.UnionCase( ucref,_) -> Some ucref| _ -> None) rest
256- let tcref = ucref1.TyconRef
257- (* Choose the first ucref based on ordering of names*)
258- let others =
259- tcref.UnionCasesAsRefList
260- |> List.filter( fun ucref -> not ( List.exists( g.unionCaseRefEq ucref) ucrefs))
261- |> List.sortBy( fun ucref -> ucref.CaseName)
262- match otherswith
263- | [] -> raise CannotRefute
264- | ucref2:: _ ->
265- let flds = ucref2|> actualTysOfUnionCaseFields( mkTyconRefInst tcref tinst) |> mkUnknowns
266- Expr.Op( TOp.UnionCase( ucref2), tinst, flds, m), false
254+ | ( DecisionTreeTest.UnionCase( ucref1, tinst) :: rest) ->
255+ let ucrefs = ucref1:: List.choose( function DecisionTreeTest.UnionCase( ucref,_) -> Some ucref| _ -> None) rest
256+ let tcref = ucref1.TyconRef
257+ (* Choose the first ucref based on ordering of names*)
258+ let others =
259+ tcref.UnionCasesAsRefList
260+ |> List.filter( fun ucref -> not ( List.exists( g.unionCaseRefEq ucref) ucrefs))
261+ |> List.sortBy( fun ucref -> ucref.CaseName)
262+ match otherswith
263+ | [] -> raise CannotRefute
264+ | ucref2:: _ ->
265+ let flds = ucref2|> actualTysOfUnionCaseFields( mkTyconRefInst tcref tinst) |> mkUnknowns
266+ Expr.Op( TOp.UnionCase( ucref2), tinst, flds, m), false
267267
268- | [ DecisionTreeTest.ArrayLength( n, ty)] ->
269- Expr.Op( TOp.Array,[ ty], mkUnknowns( List.replicate( n+ 1 ) ty) , m), false
268+ | [ DecisionTreeTest.ArrayLength( n, ty)] ->
269+ Expr.Op( TOp.Array,[ ty], mkUnknowns( List.replicate( n+ 1 ) ty) , m), false
270270
271271| _ ->
272272 raise CannotRefute
273273 go path tm
274274
275275let rec CombineRefutations g r1 r2 =
276- match r1, r2with
277- | Expr.Val( vref,_,_), other| other, Expr.Val( vref,_,_) when vref.LogicalName= " _" -> other
278- | Expr.Val( vref,_,_), other| other, Expr.Val( vref,_,_) when vref.LogicalName= notNullText-> other
279- | Expr.Val( vref,_,_), other| other, Expr.Val( vref,_,_) when vref.LogicalName= otherSubtypeText-> other
276+ match r1, r2with
277+ | Expr.Val( vref,_,_), other| other, Expr.Val( vref,_,_) when vref.LogicalName= " _" -> other
278+ | Expr.Val( vref,_,_), other| other, Expr.Val( vref,_,_) when vref.LogicalName= notNullText-> other
279+ | Expr.Val( vref,_,_), other| other, Expr.Val( vref,_,_) when vref.LogicalName= otherSubtypeText-> other
280280
281- | Expr.Op(( TOp.ExnConstr( ecref1) as op1), tinst1, flds1, m1), Expr.Op( TOp.ExnConstr( ecref2), _, flds2,_) when tyconRefEq g ecref1 ecref2->
281+ | Expr.Op(( TOp.ExnConstr( ecref1) as op1), tinst1, flds1, m1), Expr.Op( TOp.ExnConstr( ecref2), _, flds2,_) when tyconRefEq g ecref1 ecref2->
282282 Expr.Op( op1, tinst1, List.map2( CombineRefutations g) flds1 flds2, m1)
283283
284- | Expr.Op(( TOp.UnionCase( ucref1) as op1), tinst1, flds1, m1),
285- Expr.Op( TOp.UnionCase( ucref2), _, flds2,_) ->
286- if g.unionCaseRefEq ucref1 ucref2then
287- Expr.Op( op1, tinst1, List.map2( CombineRefutations g) flds1 flds2, m1)
288- (* Choose the greater of the two ucrefs based on name ordering*)
289- elif ucref1.CaseName< ucref2.CaseNamethen
290- r2
291- else
292- r1
284+ | Expr.Op(( TOp.UnionCase( ucref1) as op1), tinst1, flds1, m1), Expr.Op( TOp.UnionCase( ucref2), _, flds2,_) ->
285+ if g.unionCaseRefEq ucref1 ucref2then
286+ Expr.Op( op1, tinst1, List.map2( CombineRefutations g) flds1 flds2, m1)
287+ (* Choose the greater of the two ucrefs based on name ordering*)
288+ elif ucref1.CaseName< ucref2.CaseNamethen
289+ r2
290+ else
291+ r1
293292
294- | Expr.Op( op1, tinst1, flds1, m1), Expr.Op(_, _, flds2,_) ->
293+ | Expr.Op( op1, tinst1, flds1, m1), Expr.Op(_, _, flds2,_) ->
295294 Expr.Op( op1, tinst1, List.map2( CombineRefutations g) flds1 flds2, m1)
296295
297- | Expr.Const( c1, m1, ty1), Expr.Const( c2,_,_) ->
298- let c12 =
299-
300- // Make sure longer strings are greater, not the case in the default ordinal comparison
301- // This is needed because the individual counter examples make longer strings
302- let MaxStrings s1 s2 =
303- let c = compare( String.length s1) ( String.length s2)
304- if c< 0 then s2
305- elif c> 0 then s1
306- elif s1< s2then s2
307- else s1
308-
309- match c1, c2with
310- | Const.String( s1), Const.String( s2) -> Const.String( MaxStrings s1 s2)
311- | Const.Decimal( s1), Const.Decimal( s2) -> Const.Decimal( max s1 s2)
312- | _ -> max c1 c2
313-
314- (* REVIEW: we could return a better enumeration literal field here if a field matches one of the enumeration cases*)
315- Expr.Const( c12, m1, ty1)
316-
317- | _ -> r1
318-
319- let ShowCounterExample g denv m refuted =
320- try
321- let refutations = refuted|> List.collect( function RefutedWhenClause-> [] | ( RefutedInvestigation( path, discrim)) -> [ RefuteDiscrimSet g m path discrim])
322- let counterExample , enumCoversKnown =
323- match refutationswith
324- | [] -> raise CannotRefute
325- | ( r, eck) :: t->
326- if verbosethen dprintf" r =%s (enumCoversKnownValue =%b )\n " ( Layout.showL( exprL r)) eck
327- List.fold( fun ( rAcc , eckAcc ) ( r , eck ) ->
328- CombineRefutations g rAcc r, eckAcc|| eck) ( r, eck) t
329- let text = Layout.showL( NicePrint.dataExprL denv counterExample)
330- let failingWhenClause = refuted|> List.exists( function RefutedWhenClause-> true | _ -> false )
331- Some( text, failingWhenClause, enumCoversKnown)
332-
333- with
334- | CannotRefute->
335- None
336- | e->
337- warning( InternalError( sprintf" <failure during counter example generation:%s >" ( e.ToString()), m))
338- None
296+ | Expr.Const( c1, m1, ty1), Expr.Const( c2,_,_) ->
297+ let c12 =
298+
299+ // Make sure longer strings are greater, not the case in the default ordinal comparison
300+ // This is needed because the individual counter examples make longer strings
301+ let MaxStrings s1 s2 =
302+ let c = compare( String.length s1) ( String.length s2)
303+ if c< 0 then s2
304+ elif c> 0 then s1
305+ elif s1< s2then s2
306+ else s1
307+
308+ match c1, c2with
309+ | Const.String( s1), Const.String( s2) -> Const.String( MaxStrings s1 s2)
310+ | Const.Decimal( s1), Const.Decimal( s2) -> Const.Decimal( max s1 s2)
311+ | _ -> max c1 c2
312+
313+ Expr.Const( c12, m1, ty1)
314+
315+ | _ -> r1
316+
317+ let ShowCounterExample g denv m refuted =
318+ try
319+ let refutations = refuted|> List.collect( function RefutedWhenClause-> [] | ( RefutedInvestigation( path, discrim)) -> [ RefuteDiscrimSet g m path discrim])
320+ let counterExample , enumCoversKnown =
321+ match refutationswith
322+ | [] -> raise CannotRefute
323+ | ( r, eck) :: t->
324+ if verbosethen dprintf" r =%s (enumCoversKnownValue =%b )\n " ( Layout.showL( exprL r)) eck
325+ List.fold( fun ( rAcc , eckAcc ) ( r , eck ) ->
326+ CombineRefutations g rAcc r, eckAcc|| eck) ( r, eck) t
327+ let text = Layout.showL( NicePrint.dataExprL denv counterExample)
328+ let failingWhenClause = refuted|> List.exists( function RefutedWhenClause-> true | _ -> false )
329+ Some( text, failingWhenClause, enumCoversKnown)
330+
331+ with
332+ | CannotRefute->
333+ None
334+ | e->
335+ warning( InternalError( sprintf" <failure during counter example generation:%s >" ( e.ToString()), m))
336+ None
339337
340338//---------------------------------------------------------------------------
341339// Basic problem specification