3

Say I have an expression that has multiple subvalues how do I return the definition that would be applied to it.

Say I define for example:

fun[y_][x_] := {x, y};
fun[3][x_] := 2;

Then I would like findSubValue[fun[3][5]] to return HoldPattern[fun[3][x_]] :> 2.

Kvothe
  • 4,419
  • 9
  • 28

2 Answers2

5

How about something like this:

SetAttributes[FindMatchingSubValue, HoldAll];
FindMatchingSubValue[sym_, expr_] := 
  SelectFirst[SubValues[sym], MatchQ[Unevaluated[expr], First@#] &]

Testing:

FindMatchingSubValue[fun, fun[3][5]]
(*HoldPattern[fun[3][x_]] :> 2*)

FindMatchingSubValue[fun, fun[4][5]] (HoldPattern[fun[y_][x_]] :> {x, y})

lericr
  • 27,668
  • 1
  • 18
  • 64
0

I think the following works because SubValues are automatically sorted (according to specificity, see https://mathematica.stackexchange.com/a/106093/45020) in the list returned by SubValues (or DownValues etc...):

SetAttributes[outermostHeadHeld,HoldAllComplete];
outermostHeadHeld[expr_]:=ReleaseHold[Hold[expr]//.Hold[h_[___]]:>Hold[h]];

SetAttributes[findSubValue,HoldAll]; findSubValue[expr_]:= Module[{subvals}, subvals=SubValues[Evaluate[outermostHeadHeld[expr]]]; SelectFirst[subvals,MatchQ[Hold[expr],Hold[Evaluate[#[[1]]]]]&] ]

The same idea should also work for DownValues.

Kvothe
  • 4,419
  • 9
  • 28