%mathpiper,def="PartFracExpand"

/* Partial fraction expansion of g/f with Degree(g)<Degree(f) */
PartFracExpand(_g,_f) <--
[
  Local(mlist,vlist,res);

  mlist:=Map("^",Transpose(Factors(f)));
  vlist:=Map("Rem",{FillList(g,Length(mlist)),mlist});

  If(IsInteger(f),
    [
        Local(t,r,m);

        res:=ChineseRemainderInteger(mlist,vlist)[2];

        r := {};
        m := {};

        ForEach(t, Transpose({res,mlist})) [
            Local(f,p,c,n);

            f := Factors(t[2])[1];

            p := f[1];
            c := Sign(t[1])*PAdicExpandInternal(Abs(t[1]), p);

            r := Concat(r, Reverse(c));
            m := Concat(m, MapSingle({{n}, p^n}, (1 .. f[2])));
        ];

        res := r;
        mlist := m;
    ],
    [
        Local(t,r,m);

        res := ChineseRemainderPoly(mlist,vlist)[2];

        r := {};
        m := {};

        ForEach(t, Transpose({res,mlist})) [
            Local(f,p,c,n);

            f := Factors(t[2])[1];

            p := f[1];
            c := PAdicExpandInternal(t[1], p);

            r := Concat(r, Reverse(c));
            m := Concat(m, MapSingle({{n}, p^n}, (1 .. f[2])));
        ];

        res := r;
        mlist := m;
    ]
  );

  Local(result,divlist);

  divlist:=Map("/",{res,mlist});

  If(Length(divlist)<2,
    Add(divlist),
    [
      result:=divlist[1];
      ForEach(item,Rest(divlist))
      [
        result:=ListToFunction({ToAtom("+"),result,item});
      ];
      result;
    ]);
];

%/mathpiper
