Selectively clear DownValues

15

2

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

Posted 2012-07-06T10:57:26.157

Reputation: 81 905

3

Related: http://stackoverflow.com/q/5086749/618728

– Mr.Wizard – 2012-07-06T11:30:52.487

@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 – 2012-07-06T13:09:47.977

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 – 2012-07-06T14:36:29.023

Answers

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

Posted 2012-07-06T10:57:26.157

Reputation: 259 163

Thanks, this is just what I needed. I've used Repeated[_?NumericQ,{n}] to get a function that removes downvalues with n arguments. – Simon Woods – 2012-07-06T13:07:40.647

@Simon glad I could help. That is a good generalization. – Mr.Wizard – 2012-07-06T13:13:35.167