%mathpiper,def="MacroSubstitute"

/*Extremely hacky workaround, MacroSubstitute is actually the same as Substitute,
  but without re-evaluating its arguments. I could not just change Substitute, as
  it changed behaviour such that tests started to break.
 */
Function("MacroSubstitute",{body,predicate,change})
[
  `MacroSubstitute((Hold(@body)));
];
HoldArgument("MacroSubstitute",predicate);
HoldArgument("MacroSubstitute",change);
UnFence("MacroSubstitute",3);
Rulebase("MacroSubstitute",{body});
UnFence("MacroSubstitute",1);

Rule("MacroSubstitute",1,1,`ApplyFast(predicate,{Hold(Hold(@body))}) = True)
[
  `ApplyFast(change,{Hold(Hold(@body))});
];
Rule("MacroSubstitute",1,2,`IsFunction(Hold(@body)))
[
  `ApplyFast("MacroMapArgs",{Hold(Hold(@body)),"MacroSubstitute"});
];
Rule("MacroSubstitute",1,3,True)
[
 `Hold(@body);
];

%/mathpiper