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

LocalSymbols(LocResult) [

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

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

  LocChange(_exp) <-- LocResult;
]; // LocalSymbols(LocResult) 

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

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

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

CompilePatterns(patterns) := LocPatterns(LocProcess(patterns));


5 # (_expression /: LocPatterns(_patterns)) <--
[
  MacroSubstitute(expression,"LocPredicate","LocChange");
];
10 # (_expression /: _patterns) <--
[
  Set(patterns, LocProcess(patterns));
  MacroSubstitute(expression,"LocPredicate","LocChange");
];

5 # (_expression /:: LocPatterns(_patterns)) <--
[
  MacroSubstitute(expression,"LocPredicate","LocChange");
];
10 # (_expression /:: _patterns) <--
[
  Local(old);
  Set(patterns, LocProcess(patterns));
  Set(old, expression);
  Set(expression, MacroSubstitute(expression,"LocPredicate","LocChange"));
  While (expression != old)
  [
    Set(old, expression);
    Set(expression, MacroSubstitute(expression,"LocPredicate","LocChange"));
  ];
  expression;
];


RuleBase("Where",{left,right});
//HoldArg("Where",left);
//HoldArg("Where",right);
UnFence("Where",2);
10 # (_body Where var_IsAtom == _value)
     <-- `[Local(@var);@var := @value;@body;];
20 # (_body Where (_a And _b))
     <--
[
  Set(body,`(@body Where @a));
  `(@body Where @b);
];

30 # (_body Where {}) <-- {};
40 # (_body Where list_IsList)_IsList(list[1])
     <--
     [
       Local(head,rest);
       head:=Head(list);
       rest:=Tail(list);
       rest:= `(@body Where @rest);
       `(@body Where @head) : rest;
     ];

50 # (_body Where list_IsList)
     <--
     [
       Local(head,rest);
       While (list != {})
       [
          head:=Head(list);
          body := `(@body Where @head);
          list:=Tail(list);
        ];
        body;
     ];


60 # (_body Where _var == _value) <-- Subst(var,value)body;



// (a or b) and (c or d) -> (a and c) or (a and d) or (b and c) or (b and d)
20 # (list_IsList AddTo _rest) <--
[
  Local(res);
  res:={};
  ForEach(item,list)
  [
    res := Concat(res,item AddTo rest);
  ];
  res;
];
30 # (_a'item AddTo list_IsList) <--
[
  MapSingle({{orig},a'item And orig},list);
];
40 # (_a'item AddTo _b) <-- a'item And b;







