Это мое настоящее решение проблемы, но, как уже упоминалось в этом вопросе, оно не выглядит строго как шаблон 100 * * и не очень элегантно.
Сохраните DownValues
для f
In[6]:= dv = DownValues[f]
Out[6]= {HoldPattern[f[1]] :> 3, HoldPattern[f[x_]] :> (f[x] = x + a)}
Найдите DownValues
для очистки внутри Block
, чтобы избежать немедленной оценки
In[7]:= dv2clear = Block[{f},
Hold@Evaluate@Cases[dv,
HoldPattern[f[args__ /; Apply[And, NumericQ /@ Flatten[{args}]]]], {3}]]
Out[7]= Hold[{f[1]}]
Примените Unset
к целевому DownValues
в удерживаемом списке и затем отпустите
In[8]:= Map[Unset, dv2clear, {2}]
ReleaseHold@%
Out[8]= Hold[{(f[1]) =.}]
Это отлично работает
In[10]:= DownValues[f]
Out[10]= {HoldPattern[f[x_]] :> (f[x] = x + a)}
И можно обернуть так:
ClearCache[f_] := Module[{dv, dv2clear},
(* Cache downvalues for use inside block *)
dv = DownValues[f];
(* Find the downvalues to clear in Block to avoid immediate evaluation *)
dv2clear = Block[{f},Hold@Evaluate@Cases[dv,HoldPattern[
f[args__ /; Apply[And, NumericQ /@ Flatten[{args}]]]], {3}]];
(* Apply Unset to the terms inside the held list and then release *)
ReleaseHold@Map[Unset, dv2clear, {2}];]