func Mul(U, V PS) PS {
	Z := mkPS()
	go func() {
		<-Z.req
		uv := get2(U, V)
		if end(uv[0]) != 0 || end(uv[1]) != 0 {
			Z.dat <- finis
		} else {
			Z.dat <- mul(uv[0], uv[1])
			UU := Split(U)
			VV := Split(V)
			W := Add(Cmul(uv[0], VV[0]), Cmul(uv[1], UU[0]))
			<-Z.req
			Z.dat <- get(W)
			copy(Add(W, Mul(UU[1], VV[1])), Z)
		}
	}()
	return Z
}
simple pole at 1: 1/(1-x) = 1 1 1 1 1 ...
Convert array of coefficients, constant term first
to a (finite) power series
/*
func Poly(a []rat) PS {
Z:=mkPS()
begin func(a []rat, Z PS) {
j:=0
done:=0
for j=len(a); !done&&j>0; j=j-1)
if(a[j-1].num!=0) done=1
i:=0
for(; i<j; i=i+1) put(a[i],Z)
put(finis,Z)
}()
return Z
}

Multiply. The algorithm is
let U = u + x*UU
let V = v + x*VV
then UV = u*v + x*(u*VV+v*UU) + x*x*UU*VV
package main
import "os"
type rat struct {
	num, den int64  
}
func (u rat) pr() {
	if u.den == 1 {
		print(u.num)
	} else {
		print(u.num, "/", u.den)
	}
	print(" ")
}
func (u rat) eq(c rat) bool {
	return u.num == c.num && u.den == c.den
}
type dch struct {
	req chan int
	dat chan rat
	nam int
}
type dch2 [2]*dch
var chnames string
var chnameserial int
var seqno int
func mkdch() *dch {
	c := chnameserial % len(chnames)
	chnameserial++
	d := new(dch)
	d.req = make(chan int)
	d.dat = make(chan rat)
	d.nam = c
	return d
}
func mkdch2() *dch2 {
	d2 := new(dch2)
	d2[0] = mkdch()
	d2[1] = mkdch()
	return d2
}
func dosplit(in *dch, out *dch2, wait chan int) {
	both := false  
	select {
	case <-out[0].req:
	case <-wait:
		both = true
		select {
		case <-out[0].req:
		case <-out[1].req:
			out[0], out[1] = out[1], out[0]
		}
	}
	seqno++
	in.req <- seqno
	release := make(chan int)
	go dosplit(in, out, release)
	dat := <-in.dat
	out[0].dat <- dat
	if !both {
		<-wait
	}
	<-out[1].req
	out[1].dat <- dat
	release <- 0
}
func split(in *dch, out *dch2) {
	release := make(chan int)
	go dosplit(in, out, release)
	release <- 0
}
func put(dat rat, out *dch) {
	<-out.req
	out.dat <- dat
}
func get(in *dch) rat {
	seqno++
	in.req <- seqno
	return <-in.dat
}
func getn(in []*dch) []rat {
	n := len(in)
	if n != 2 {
		panic("bad n in getn")
	}
	req := new([2]chan int)
	dat := new([2]chan rat)
	out := make([]rat, 2)
	var i int
	var it rat
	for i = 0; i < n; i++ {
		req[i] = in[i].req
		dat[i] = nil
	}
	for n = 2 * n; n > 0; n-- {
		seqno++
		select {
		case req[0] <- seqno:
			dat[0] = in[0].dat
			req[0] = nil
		case req[1] <- seqno:
			dat[1] = in[1].dat
			req[1] = nil
		case it = <-dat[0]:
			out[0] = it
			dat[0] = nil
		case it = <-dat[1]:
			out[1] = it
			dat[1] = nil
		}
	}
	return out
}
func get2(in0 *dch, in1 *dch) []rat {
	return getn([]*dch{in0, in1})
}
func copy(in *dch, out *dch) {
	for {
		<-out.req
		out.dat <- get(in)
	}
}
func repeat(dat rat, out *dch) {
	for {
		put(dat, out)
	}
}
type PS *dch     
type PS2 *[2]PS  
var Ones PS
var Twos PS
func mkPS() *dch {
	return mkdch()
}
func mkPS2() *dch2 {
	return mkdch2()
}
func gcd(u, v int64) int64 {
	if u < 0 {
		return gcd(-u, v)
	}
	if u == 0 {
		return v
	}
	return gcd(v%u, u)
}
func i2tor(u, v int64) rat {
	g := gcd(u, v)
	var r rat
	if v > 0 {
		r.num = u / g
		r.den = v / g
	} else {
		r.num = -u / g
		r.den = -v / g
	}
	return r
}
func itor(u int64) rat {
	return i2tor(u, 1)
}
var zero rat
var one rat
var finis rat
func end(u rat) int64 {
	if u.den == 0 {
		return 1
	}
	return 0
}
func add(u, v rat) rat {
	g := gcd(u.den, v.den)
	return i2tor(u.num*(v.den/g)+v.num*(u.den/g), u.den*(v.den/g))
}
func mul(u, v rat) rat {
	g1 := gcd(u.num, v.den)
	g2 := gcd(u.den, v.num)
	var r rat
	r.num = (u.num / g1) * (v.num / g2)
	r.den = (u.den / g2) * (v.den / g1)
	return r
}
func neg(u rat) rat {
	return i2tor(-u.num, u.den)
}
func sub(u, v rat) rat {
	return add(u, neg(v))
}
func inv(u rat) rat {  
	if u.num == 0 {
		panic("zero divide in inv")
	}
	return i2tor(u.den, u.num)
}
func evaln(c rat, U PS, n int) {
	xn := float64(1)
	x := float64(c.num) / float64(c.den)
	val := float64(0)
	for i := 0; i < n; i++ {
		u := get(U)
		if end(u) != 0 {
			break
		}
		val = val + x*float64(u.num)/float64(u.den)
		xn = xn * x
	}
	print(val, "\n")
}
func printn(U PS, n int) {
	done := false
	for ; !done && n > 0; n-- {
		u := get(U)
		if end(u) != 0 {
			done = true
		} else {
			u.pr()
		}
	}
	print(("\n"))
}
func eval(c rat, U PS, n int) rat {
	if n == 0 {
		return zero
	}
	y := get(U)
	if end(y) != 0 {
		return zero
	}
	return add(y, mul(c, eval(c, U, n-1)))
}
func Split(U PS) *dch2 {
	UU := mkdch2()
	go split(U, UU)
	return UU
}
func Add(U, V PS) PS {
	Z := mkPS()
	go func() {
		var uv []rat
		for {
			<-Z.req
			uv = get2(U, V)
			switch end(uv[0]) + 2*end(uv[1]) {
			case 0:
				Z.dat <- add(uv[0], uv[1])
			case 1:
				Z.dat <- uv[1]
				copy(V, Z)
			case 2:
				Z.dat <- uv[0]
				copy(U, Z)
			case 3:
				Z.dat <- finis
			}
		}
	}()
	return Z
}
func Cmul(c rat, U PS) PS {
	Z := mkPS()
	go func() {
		done := false
		for !done {
			<-Z.req
			u := get(U)
			if end(u) != 0 {
				done = true
			} else {
				Z.dat <- mul(c, u)
			}
		}
		Z.dat <- finis
	}()
	return Z
}
func Sub(U, V PS) PS {
	return Add(U, Cmul(neg(one), V))
}
func Monmul(U PS, n int) PS {
	Z := mkPS()
	go func() {
		for ; n > 0; n-- {
			put(zero, Z)
		}
		copy(U, Z)
	}()
	return Z
}
func Xmul(U PS) PS {
	return Monmul(U, 1)
}
func Rep(c rat) PS {
	Z := mkPS()
	go repeat(c, Z)
	return Z
}
func Mon(c rat, n int) PS {
	Z := mkPS()
	go func() {
		if c.num != 0 {
			for ; n > 0; n = n - 1 {
				put(zero, Z)
			}
			put(c, Z)
		}
		put(finis, Z)
	}()
	return Z
}
func Shift(c rat, U PS) PS {
	Z := mkPS()
	go func() {
		put(c, Z)
		copy(U, Z)
	}()
	return Z
}