LocalRule & Local Set operators

*To*: mathgroup at smc.vnet.net*Subject*: [mg13908] LocalRule & Local Set operators*From*: "Ersek, Ted R" <ErsekTR at navair.navy.mil>*Date*: Sun, 6 Sep 1998 02:55:44 -0400*Sender*: owner-wri-mathgroup at wolfram.com

Recall the messages I sent on 28 Aug and 29 Aug. [mg13812] An operator called-- LocalRule [mg13835] An operator called-- LocalSet I have improved versions of these functions below (with usage messages). The differences are: (1) The new versions will not look inside Verbatim[....] to find patterns that should be evaluated inside a local environment. (2) The new versions use a new function PatternNames which may be useful in it's own right. The program for PatternNames is a bit advanced, but it does with one application of Cases what took a few lines in my previous version. (3) This version will not have trouble if the same pattern name appears in (lhs) more than once. (e.g. f[x_, x_] ) Changes (1) and (2) are due to feedback I got from one of the gurus in the group. I understand there are still some subtle problems with these programs, but they should be useful for many applications as they are. Cheers, Ted Ersek (*********************************) Unprotect[LocalRule, RightArrow, LocalSet, DotEqual, PatternNames]; LocalRule::usage= "LocalRule[lhs,rhs] represents a rule where rhs is evaluated \ immediately using a local environment for any variable used as a \ pattern in lhs. LocalRule[lhs,rhs] is equivalent to \ lhs\[RightArrow]rhs where \[RightArrow] is entered \ as \\[RightArrow]."; RightArrow::usage= "lhs\[RightArrow]rhs represents a rule where rhs is evaluated \ immediately using a local environment for any variables used as a\ pattern in lhs. Note: \[RightArrow] is entered as \\[RightArrow].\ The expression lhs\[RightArrow]rhs is equivalent to \ LocalRule[lhs,rhs]."; LocalSet::usage= "LocalSet[lhs,rhs] evaluates rhs using a local environment for any \ variable used as a pattern in lhs. From then on lhs is replaced by the \ result of evaluating rhs whenever lhs appears. LocalSet[lhs,rhs] is \ equivalent to lhs\[DotEqual]rhs where \[DotEqual] is entered \ as \\[DotEqual]."; DotEqual::usage= "lhs\[DotEqual]rhs evaluates rhs using a local environment for any \ variable used as a pattern in lhs. From then on lhs is replaced by \ the result of evaluating rhs whenever lhs appears. The expression \ lhs\[DotEqual]rhs, is equivalent to LocalSet[lhs,rhs]."; PatternNames::usage= "PatternNames[expr] returns a list of the names of patterns \ included in expr. The list returned is wrapped in Hold. \ PatternNames does not consider patterns that appear inside Verbatim. \ Example:\n PatternNames[foo[a_,b_:1,c_?NumericQ,d,e]] returns \n Hold[{a,b,c}]."; LocalSet=DotEqual; LocalRule=RightArrow; Attributes[DotEqual]={HoldAll,SequenceHold}; Attributes[RightArrow]={HoldRest,SequenceHold}; Attributes[PatternNames] = {HoldFirst}; PatternNames[lhs__] := Module[{lhsWithoutVerbatim, heldNames}, lhsWithoutVerbatim = ReplaceAll[Hold[lhs], _Verbatim -> Null]; heldNames = Cases[lhsWithoutVerbatim, Verbatim[Pattern][name_Symbol,_] :> Hold[name], {0,-2}, Heads -> True ]; Thread[Union at heldNames, Hold] ] RightArrow[lhs_,rhs_]:=Module[{q}, q=PatternNames[lhs]; If[q==={},(lhs:>Evaluate at rhs), Block@@Join[q,Hold[lhs:>Evaluate at rhs] ] ]] DotEqual[lhs_,rhs_]:=Module[{b1,b2},( b1=PatternNames[lhs]; If[b1==={},(Unevaluated at lhs:=Evaluate at rhs), b2=Hold[#:=Evaluate at rhs]& @@{Unevaluated at lhs}; Block@@Join[b1,b2] ] )] Protect[LocalRule, RightArrow, LocalSet, DotEqual, PatternNames];