%mathpiper,def="MultiDivide"

//Retract("MultiDivide",*);

/*************************************************************
  MultiDivide :
  input
    f - a multivariate polynomial
    g[1 .. n] - a list of polynomials to divide by
  output
    {q[1 .. n],r} such that f = q[1]*g[1] + ... + q[n]*g[n] + r

  Basically quotient and remainder after division by a group of
  polynomials.
  
  110709    Corrected error in if-Select statement  (hao)
**************************************************************/

20 # MultiDivide(_f,g_IsList) <--
[
  If(InVerboseMode(),Tell("MultiDivide_1",{f,g}));
  Local(i,v,q,r,nr);
  v  := MultiExpressionList(f+Sum(g));
  f  := MakeMultiNomial(f,v);
  nr := Length(g);
  For(i:=1,i<=nr,i++)
  [
    g[i] := MakeMultiNomial(g[i],v);
  ];
  If(Not IsMulti(f),Break());
  {q,r} := MultiDivide(f,g);
  q     := MapSingle("NormalForm",q);
  r     := NormalForm(r);
  {q,r};
];


10 # MultiDivide(f_IsMulti,g_IsList) <--
[
  If(InVerboseMode(),Tell("MultiDivide_2",{f,g}));
  Local(i,nr,q,r,p,v,finished);
  nr := Length(g);
  v  := MultiVars(f);
  q  := FillList(0,nr);
  r  := 0;
  p  := f;
  finished := MultiZero(p);
  Local(plt,glt);
  While (Not finished)
  [
    plt := MultiLT(p);  //  MultiLT computes the multi-LeadingTerm
    For(i:=1,i<=nr,i++)
    [
      glt := MultiLT(g[i]);

      if (MultiLM(glt) = MultiLM(plt) Or MultiTermLess({MultiLM(glt),1}, {MultiLM(plt),1}))
      [
        //   corrected if-select statement  110708    hso
        if (Select(MultiLM(plt)-MultiLM(glt),{{n},n<0}) = {} )
        [
          Local(ff,ltbefore,ltafter);
          ff := CreateTerm(v,{MultiLM(plt)-MultiLM(glt),MultiLC(plt)/MultiLC(glt)});
          If(InVerboseMode(),Tell("      ",NormalForm(ff)));
          q[i] := q[i] + ff;
          ltbefore := MultiLeadingTerm(p);
          p := p - ff*g[i];
          ltafter := MultiLeadingTerm(p);
          if (ltbefore[1] = ltafter[1])
          [
            ltafter := MultiLT(p);
            p       := p-ltafter;
          ];
//          Echo(ltbefore,MultiLeadingTerm(p));
          i := nr + 2;
        ];
      ];
    ];

    If (i = nr + 1,
      [
        r := r + LocalSymbols(a,b)(Subst(a,b)plt);
        p := p - LocalSymbols(a,b)(Subst(a,b)plt);
      ]
    );
    finished := MultiZero(p);
  ];
  {q,r};
];

%/mathpiper

