16

How can I clear a subset of a symbol's DownValues ?

For example, suppose I have created some DownValues for $f$ like this:

(f[Sequence @@ #] = Plus @@ #) & /@ Subsets[{1, 2, 3}];
f[x_, y_] := x y

DownValues[f]    
(*  {HoldPattern[f[]] :> 0, HoldPattern[f[1]] :> 1, 
 HoldPattern[f[2]] :> 2, HoldPattern[f[3]] :> 3, 
 HoldPattern[f[1, 2]] :> 3, HoldPattern[f[1, 3]] :> 4, 
 HoldPattern[f[2, 3]] :> 5, HoldPattern[f[1, 2, 3]] :> 6, 
 HoldPattern[f[x_, y_]] :> x y}  *)

I now wish to clear all the downvalues for which $f$ has exactly $n$ numerical arguments. In other words I would like to have a function selectiveClear[f,n] such that this would happen:

selectiveClear[f,2]
DownValues[f]
(*  {HoldPattern[f[]] :> 0, HoldPattern[f[1]] :> 1, 
 HoldPattern[f[2]] :> 2, HoldPattern[f[3]] :> 3, 
 HoldPattern[f[1, 2, 3]] :> 6, HoldPattern[f[x_, y_]] :> x y}  *)

I have tried using Cases to pick a subset of the DownValues, but I can't seem to get the pattern correct.

Simon Woods
  • 84,945
  • 8
  • 175
  • 324
  • 3
    Related: http://stackoverflow.com/q/5086749/618728 – Mr.Wizard Jul 06 '12 at 11:30
  • @Mr.Wizard, the link is very useful too, thanks. I always forget to search on stackoverflow. It would be nice if the Mathematica questions on there could be imported into this site somehow. – Simon Woods Jul 06 '12 at 13:09
  • They can be imported, but only on a case-by-case basis as they're still generally on-topic over there. We have to beg and plead for them to be migrated, and it rarely happens with questions that are older with good answers already. – rcollyer Jul 06 '12 at 14:36

1 Answers1

16
DownValues[f] = 
 DeleteCases[DownValues[f], _@_[_?NumericQ, _?NumericQ] :> _]
{HoldPattern[f[]] :> 0, HoldPattern[f[1]] :> 1, 
 HoldPattern[f[2]] :> 2, HoldPattern[f[3]] :> 3, 
 HoldPattern[f[1, 2, 3]] :> 6, HoldPattern[f[x_, y_]] :> x y}

It is possible to make this pattern fail if you want also to clear something like:

f[1, 2] /; $op := "$op is active"

This would catch it:

DeleteCases[
 DownValues[f],
 (x_ :> _) /; ! x ~FreeQ~ Verbatim[f][_?NumericQ, _?NumericQ]
]

Szabolcs remarks it is valuable to mention Unset in this context.
I described the use of that and related functions here.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371