(* bilo.ruleFormation *) (* Section 1 -- infrastructure *) listOfVariables[s_] := Module[{f, a, b, x}, Union[ Select[s //. f_[a___][b___] :> f[a, b] // If[AtomQ[#], {#}, List @@ #]& // FixedPoint[ Composition[Flatten, ((# /. f_[x___] :> {x})& /@ #)&], #]&, MatchQ[#, _Symbol] && FreeQ[Attributes[#], Protected]&]]] restrictedListOfVariables[s_] := Union[Select[Level[s, {-1}], MatchQ[#, _Symbol] && FreeQ[Attributes[#], Protected]&]] extendedListOfVariables[s_] := Union[Select[Level[s, {-1}, Heads -> True], MatchQ[#, _Symbol] && FreeQ[Attributes[#], Protected]&]] patternizer[vList_] := (# :> Pattern[#, Blank[]])& /@ vList patternized[s_] := s /. patternizer[listOfVariables[s]] (* Section 2 -- ruleFor construction *) relPat = lhs_ ~ op_?rhm ~ rhs_; nullRule = Identity :> Identity; Protect[relPat, nullRule]; bruleFor[s_] := Switch[s, relPat, RuleDelayed @@ s, _List, bruleFor /@ s, _, nullRule] gruleFor[s_] := Switch[s, relPat, RuleDelayed @@ {patternized[s[[1]]], s[[2]]}, _List, gruleFor /@ s, _, nullRule] cruleFor[s_][v___] := Module[{oldList, newList}, Switch[s, relPat, oldList = listOfVariables[s]; newList = {v}; RuleDelayed @@ s /. (Switch[newList[[#]], Null, Null, null, oldList[[#]] :> Null, _, Rule @@ {oldList[[#]], newList[[#]]}]& /@ Range[Length[newList]] // deleteNullElements), _List, cruleFor[#][v]& /@ s, _, nullRule]] hruleFor[s_][x___][y___] := Module[{xList, yList, interim, newLhs}, Switch[s, relPat, xList = {x}; yList = {y}; If[Length[xList] != Length[yList], Return[nullRule]]; interim = s /. MapThread[Rule, {xList, yList}]; newLhs = interim[[1]]; toBePatternized = Complement @@ listOfVariables /@ {newLhs, yList}; RuleDelayed @@ {newLhs /. patternizer[ Complement @@ listOfVariables /@ {newLhs, yList}], interim[[2]]}, _List, hruleFor[#][x][y]& /@ s, _, nullRule]] (* Section 3 -- ruleReverseFor construction *) bruleReverseFor[s_] := Switch[s, relPat, bruleFor[reverse[s]], _List, bruleReverseFor /@ s, _, nullRule] gruleReverseFor[s_] := Switch[s, relPat, gruleFor[reverse[s]], _List, gruleReverseFor /@ s, _, nullRule] cruleReverseFor[s_][v___] := Switch[s, relPat, cruleFor[reverse[s]][v], _List, cruleReverseFor[#][v]& /@ s, _, nullRule] hruleReverseFor[_][x___][y___] := Switch[s, relPat, hruleFor[reverse[s]][x][y], _List, hruleReverseFor[#][x][y]& /@ s, _, nullRule] (* Section 4 -- rule[id] construction *) brule[id___] := Which[ValueQ[eqn[id]], bruleFor[eqn[id]], ValueQ[stmt[id]], bruleFor[stmt[id]], True, nullRule] grule[id___] := Which[ValueQ[eqn[id]], gruleFor[eqn[id]], ValueQ[stmt[id]], gruleFor[stmt[id]], True, nullRule] crule[id___][v___] := Which[ValueQ[eqn[id]], cruleFor[eqn[id]][v], ValueQ[stmt[id]], cruleFor[stmt[id]][v], True, nullRule] hrule[id___][x___][y___] := Which[ValueQ[eqn[id]], hruleFor[eqn[id]][x][y], ValueQ[stmt[id]], hruleFor[stmt[id]][x][y], True, nullRule] (* Section 5 -- ruleReverse construction *) bruleReverse[id___] := Which[ValueQ[eqn[id]], bruleReverseFor[eqn[id]], ValueQ[stmt[id]], bruleReverseFor[stmt[id]], True, nullRule] gruleReverse[id___] := Which[ValueQ[eqn[id]], gruleReverseFor[eqn[id]], ValueQ[stmt[id]], gruleReverseFor[stmt[id]], True, nullRule] cruleReverse[id___][v___] := Which[ValueQ[eqn[id]], cruleReverseFor[eqn[id]][v], ValueQ[stmt[id]], cruleReverseFor[stmt[id]][v], True, nullRule] hruleReverse[id___][x___][y___] := Which[ValueQ[eqn[id]], hruleReverseFor[eqn[id]][x][y], ValueQ[stmt[id]], hruleReverseFor[stmt[id]][x][y], True, nullRule] (* Section 5 -- "rule for expansion of" construction *) bruleForExpansionOf[s_] := bruleFor[Expand @@ {s} == s] gruleForExpansionOf[s_] := gruleFor[Expand @@ {s} == s] cruleForExpansionOf[s_] := cruleFor[Expand @@ {s} == s] hruleForExpansionOf[s_] := hruleFor[Expand @@ {s} == s] bruleReverseForExpansionOf[s_] := bruleFor[s == Expand @@ {s} == s] gruleReverseForExpansionOf[s_] := gruleFor[s == Expand @@ {s} == s] cruleReverseForExpansionOf[s_] := cruleFor[s == Expand @@ {s} == s] hruleReverseForExpansionOf[s_] := hruleFor[s == Expand @@ {s} == s] (* Section 6 -- miscellaneous *) rule[id___] := Print[" !!! bilo1 usage -- revise the input !!!"] biloRuleFormationLoaded = True;