incr-set prlevel 1
if #0=4 START 
incr-set prlevel -1

;;; Usage:
;;; 	<minpres j varlist j' f
;;;
;;; Find a minimal presentation k[varlist]/j' for a given ring R/j, 
;;; and a map f: R --> k[varlist] inducing an isomorphism
;;;           
;;;    R/j ----> k[varlist]/j'
incr-set prlevel 1
jump END
;;;
;;; Parameters:
;;;		j = ideal, possibly containing some minimal forms
;;;		varlist = a variable list suitable for the ring command
;;; Output values:
;;;		j' = an ideal in k[varlist]
;;;		f  = an ideal of linear forms and zeros in k[varlist],
;;;			representing the projection map from R.
;;; k[varlist] is of course isomorphic, via f, to R/j1, where
;;; j1 is the ideal generated by the linear forms in j.
;;;
;;; Caveats:
;;; 	If not enough variables are given, the script puts in A[1]...A[100]
; created 3/3/89 DE
START:

;Define a map from the given ring to itself
;killing all the variables:
setring #1
<getvars @vars
subtract @vars @vars @reduce

;Find the linear forms @kernel in j:
lift-std @vars @vars
lift @vars #1 @kernel
ev @reduce @kernel @kernel

;Now define a map whose kernel is generated by the linear forms
;in @kernel
transpose @kernel @kernel'
res @kernel' @map 2
transpose @map.2 @map

;Form the new ring which is R/kernel:
ncols @map @ncols
ring-from-rows @map @r
#2A[1]-A[100]


;Now we bring over @map.  Note that it doesn't matter
;what map we use, since @map is a scalar matrix.
ev @r @map @map
;To use @map we must change it from a scalar matrix to
;a row of linear forms:
<getvars @vars
mult @vars @map #4
ev #4 #1 #3


;Now produce a minimal set of generators for the ideal in the
;new ring:
std #3 #3

;The following line could be used to get the minimal set of generators
;only:
;copy #3 #3

; finally, clean up:
kill @reduce @kernel @kernel' @ncols @r'zero @r @map @vars 
END:
incr-set prlevel -1

$;;;;;;;; EXAMPLE SECTION ;;;;;;;;;;;;;;;;;;;;;;;;;
<ring 4 a-z r
ideal i
2
a+b+c+d
a2+d2
poly p cd


<minpres
<minpres i u-z I f
ev f p p
type p
; vw 
type f
; -u-v-w u v w 
