func Subst(p Process, vs, xs []Name) error {
	if len(xs) != len(vs) {
		return errSubst(ErrInvalid)
	}
	procs := []Process{p}
	for len(procs) > 0 {
		p, procs = procs[0], procs[1:]
		switch p := p.(type) {
		case *NilProcess:
		case *Par:
			procs = append(procs, p.Procs...)
		case *Recv:
			for i, x := range xs {
				if IsSameName(p.Chan, x) {
					if ch, canSetName := p.Chan.(name.Setter); canSetName {
						ch.SetName(vs[i].Ident())
					}
				}
				for _, rv := range p.Vars {
					if IsSameName(rv, x) {
						if ch, canSetName := rv.(name.Setter); canSetName {
							ch.SetName(vs[i].Ident())
						}
					}
				}
			}
			procs = append(procs, p.Cont)
		case *Restrict:
			procs = append(procs, p.Proc)
		case *Repeat:
			procs = append(procs, p.Proc)
		case *Send:
			for i, x := range xs {
				if IsSameName(p.Chan, x) {
					if ch, canSetName := p.Chan.(name.Setter); canSetName {
						ch.SetName(vs[i].Ident())
					}
				}
			}
		default:
			return errSubst(UnknownProcessError{Proc: p})
		}
	}
	return nil
}
Subst is the substitution of variables xs by names vs in Process p.

The caller must ensure that the size of xs and vs are the same
such that xs[i] is substituted by vs[i] in 0 <= i < len(xs).
package asyncpi
import (
	"go.nickng.io/asyncpi/internal/errors"
	"go.nickng.io/asyncpi/internal/name"
)
func errSubst(err error) error {
	return errors.Wrap(err, "substitution failed")
}