

RuleBase("MakeVector",{vec,dimension});
Rule("MakeVector",2,1,True)
[
    Local(res,i);
    res:={};
    i:=1;
    Set(dimension,MathAdd(dimension,1));
    While(LessThan(i,dimension))
    [
      DestructiveInsert(res,1,Atom(ConcatStrings(String(vec),String(i))));
      Set(i,MathAdd(i,1));
    ];
    DestructiveReverse(res);
];


RuleBase("<--",{patternleft,patternright});

Rule("<--",2,1,Type(patternleft) = "#")
[
  DefinePattern(patternleft[[2]],patternright,patternleft[[1]],True);
];
Rule("<--",2,2,IsFunction(patternleft))
[
 DefinePattern(patternleft,patternright,0,True);
];
HoldArg("<--",patternleft);
HoldArg("<--",patternright);

RuleBase("DefinePattern",
         {patternleft,patternright,patternprecedence,postpredicate});
Rule("DefinePattern",4,9,Type(patternleft) = "_")
[
 DefinePattern(patternleft[[1]],patternright,
               patternprecedence,patternleft[[2]]);
];

Rule("DefinePattern",4,10,True)
[
  Local(patternflat,patternvars,
        patternpredicate,patt,defvars,patternoper);
  patternflat := Listify(patternleft);
  patternvars := Tail(patternflat);
  patternoper:=String(Head(patternflat));

  If(Not(RuleBaseDefined(patternoper,Length(patternvars))),
     [
      MacroRuleBase(patternoper,MakeVector(arg,Length(patternvars)));
     ]
    );

  defvars:=RuleBaseArgList(patternoper,Length(patternvars));
  patt:=PatternCreate(patternvars,postpredicate);
  patternpredicate:=UnList({PatternMatches,patt,defvars});
  MacroRule(patternoper,Length(patternvars),patternprecedence,
            patternpredicate)patternright;
  True;
];


