
RuleBase("<-",{left,right});
HoldArg("<-",left);
HoldArg("<-",right);


10 # LocPredicate(exp_IsAtom) <--
[
  Local(tr,result);
  tr:=patterns;
  result:=False;
  While (tr != {})
  [
    If (Head(Head(tr)) = exp,
    [
      result := True;
      tr:={};
    ],
    [
      tr := Tail(tr);
    ]);
  ];
  result;
];

10 # LocPredicate(exp_IsFunction) <--
[
  Local(tr,result,head);
  tr:=patterns;
  result:=False;
  While (tr != {})
  [
    head := Head(Head(tr));
    If (Not(IsAtom(head)) And exp[0]=head[1] And PatternMatches(head[2], exp),
    [
      result := True;
      tr:={};
    ],
    [
      tr := Tail(tr);
    ]);
  ];
  result;
];
20 # LocPredicate(_exp) <-- False;

10 # LocChange(exp_IsAtom) <--
[
  Local(tr,result);
  tr:=patterns;
  result:=False;
  While (tr != {})
  [
    If (Head(Head(tr)) = exp,
    [
      result := Eval(Head(Tail(Head(tr))));
      If(Verbose, Echo({exp," replaced with ",result}));
      tr:={};
    ],
    [
      tr := Tail(tr);
    ]);
  ];
  result;
];

10 # LocChange(exp_IsFunction) <--
[
  Local(tr,result,head);
  tr:=patterns;
  result:=False;
  While (tr != {})
  [
    head := Head(Head(tr));
    If (Not(IsAtom(head)) And exp[0]=head[1] And PatternMatches(head[2], exp),
    [
      result := Eval(Head(Tail(Head(tr))));
      If(Verbose, Echo({exp," replaced with ",result}));
      tr:={};
    ],
    [
      tr := Tail(tr);
    ]);
  ];
  result;
];

UnFence("LocPredicate",1);
UnFence("LocChange",1);

10 # LocProcessSingle({_pat,_post,_exp}) <-- { {pat[0],PatternCreate(pat,post)},exp };
20 # LocProcessSingle({pat_IsFunction,_exp}) <-- { {pat[0],PatternCreate(pat,True)},exp };
30 # LocProcessSingle({pat_IsAtom,_exp}) <-- { pat,exp };
40 # LocProcessSingle(pat_IsFunction <- _exp) <-- { {pat[0],PatternCreate(pat,True)},exp };
50 # LocProcessSingle(pat_IsAtom <- _exp) <-- { pat,exp };

LocProcess(patterns) :=
[
  MapSingle("LocProcessSingle",patterns);
];

(expression /: patterns) :=
[
  patterns := LocProcess(patterns);
  Substitute(expression,"LocPredicate","LocChange");
];

(expression /:: patterns) :=
[
  Local(old);
  patterns := LocProcess(patterns);
  old := expression;
  expression := Substitute(expression,"LocPredicate","LocChange");
  While (expression != old)
  [
    old := expression;
    expression := Substitute(expression,"LocPredicate","LocChange");
  ];
  expression;
];


