<*>= [D->]
global debug, debugs, debugstack
procedure wrerr(L[])
    write ! ([&errout] ||| L)
end
procedure wrerrs(L[])
    writes ! ([&errout] ||| L)
end
procedure nop()
end

procedure debug_on()
  /debugstack := []
  every push(debugstack, debug | debugs)
  debug := wrerr
  debugs := wrerrs
  return
end

procedure debug_off()
  /debugstack := []
  every push(debugstack, debug | debugs)
  debug := debugs := nop
  return
end

procedure debug_pop()
  every debugs | debug := pop(debugstack)
  return
end

Defines debug, debug_off, debug_on, debug_pop, debugs, debugstack, nop, wrerr, wrerrs (links are to index).

<integer-input error>=
# error("unknown integer input `", image(i),"' of type `", type(i), "'")

Note this procedure doesn't parenthesize properly.

<*>+= [<-D->]
procedure astimage(n)
    return case type(n) of { 
        "pattern"  : "<pattern> " || patternimage(n)
        "Pident"   : n.name
        "Pcon"     : n.name || " " || n.relop || " " || astimage(n.value)
        "Pand"     : commaseparate(astimage(n.patterns), " & ")
        "Por"      : commaseparate(astimage(n.patterns), " | ") 
        "Pseq"     : <image of Pseq (possibly with dots)>
        "Papp"     : astimage(n.cons) || "(" || commaseparate(astimage(n.args)) || ")"
        "integer"  : n
        "string"   : n
        "Glist"    : astimage(n.values)
        "list"     : maplist(astimage, n)
        default    : image(n)
    }
end
Defines astimage (links are to index).

<image of Pseq (possibly with dots)>= (<-U)
if *n.patterns = 2 & n.patterns[1] === dots_pattern() then 
  "... " || astimage(n.patterns[2])
else if *n.patterns = 2 & n.patterns[2] === dots_pattern() then
  astimage(n.patterns[1]) || " ..."
else 
  commaseparate(astimage(n.patterns), "; ")
<*>+= [<-D->]
procedure solnimage(soln)
  s := envimage(soln.answers, "answers") || "\n"
  s ||:= "Uses " || commafy(maplist(expimage, sort(\soln.used))) || "\n"
  s ||:= "Defines " || commafy(maplist(expimage, sort(\soln.defined))) || "\n"
  s ||:= "(constraints: " || commafy(maplist(expimage, \soln.constraints)) || " )"
  return s
end
Defines solnimage (links are to index).

<*>+= [<-D->]
procedure injectimage(i)
  return "\tas pattern: " || expimage(i.pattern) || "\n" ||
         "\tas integer: " || expimage(i.integer) || "\n" ||
         "\tas consop: " || expimage(i.consop) || "\n" 
end
Defines injectimage (links are to index).

Show with positive coefficients.

<*>+= [<-D]
procedure zeroimage(z)
  e := eqn(table(0), "=", table(0))
  every k := key(z) do
    if z[k] > 0 then e.left[k] := z[k] else e.right[k] := -z[k]
  return expimage(e)
end
Defines zeroimage (links are to index).