incr-set prlevel 1
if #0=2 START
incr-set prlevel -1
;;; Usage:
;;; 	<regular_sequence1 i reg
;;;
;;; a fairly direct approach to producing a regular
;;; sequence contained in a given ideal i.  
;;;
incr-set prlevel 1
jump END
;;; Parameters:
;;;    i = ideal
;;; Output values:
;;;    reg = maximal regular sequence in i
;;; Strategy 
;;;    First order i by increasing degree.
;;;    Next, suppose that a regular sequence f of I
;;; with length k < codim I
;;; has been found, the pth
;;; element being of the form I[p] + later.  Let
;;; I2 be generated by all but the first k elements of I.
;;;     We work in the ring q modulo f.  Reducing I2
;;; we find the smallest initial subset I3 of height 1 
;;; (better?: containing a nzd?).  
;;; We define the k+1 st element of f to be a 
;;; random linear combination of the elements of I2
;;;
;;; Caveats: Slow!  regular_sequence1 represents a different
;;; strategy
;;;
; created 5/14/90 DE
START:
;find out how long a sequence we need:
std #1 @i
codim @i @codim

;put the smallest degree elements of @i first
<sort_by_degree @i @i

;begin the regular sequence, @f, with the first element
;of @i.  Note that since we have taken a standard basis, 
;it is nonzero.
submat @i @f
	1
	1
	
;drop the first element from @i, since it's been used:
ncols @i @ncols
submat @i @i
	;
	2..@ncols

;Now loop, find another element of the regular sequence each
;round:
int @n 1
nextf:
int @n @n+1
if @n>@codim finish

;The only cleverness in this script is to systematically
;work mod the part of the regular sequence already 
;constructed:
std @f @f
qring @f @q
fetch @i @i

;Find an initial subset of @i containing a nzd.
<ideal @zero 
int @m 0

	loop:
	int @m @m+1
	submat @i @j
		;
		1..@m
	quotient @zero @j @test
	<i_in_j @test @j @test
	if @test found
	jump loop

found:
;At this point @j contains the smallest initial subset of 
;@i from which the next element of the sequence can be chosen.


;Find a random element of @j.  Unfortunately, we must go
;to the degree of the largest generator of @j:
transpose @j @j'
min @j' @jmax
int @jmax -@jmax
<random_element @j @jmax @fn

;drop the first element from @i, since we have used it:
ncols @i @ncols
submat @i @i
	;
	2..@ncols

;Bring back the new element to the original ring,
;and put it in the sequence:
setring #1
fetch @fn @fn
concat @f @fn

jump nextf

finish:
copy @f #2
kill @codim @f @q'zero @q @zero @m @j @test @j' @jmax 
kill @ncols @i @fn @n 
END:
incr-set prlevel -1

$;;;;;;;; EXAMPLE SECTION ;;;;;;;;;;;;;;;;;;;;;;;;;
reset

<ring 4 a-z r
<ideal I a2b ac bc ad bd cd
<regular_sequence I F
<regular_sequence1 I F
type F
res F F
betti F
; total:      1     3     3     1 
; --------------------------------
;     0:      1     -     -     - 
;     1:      -     2     -     - 
;     2:      -     1     1     - 
;     3:      -     -     2     - 
;     4:      -     -     -     1 

listvars


; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;The following are examples which make the stupidity of
; this script at least partly necessary:

;The first example shows that it's not so easy to break the
;ideal into pieces and take a random element from each one.
;The obvious way would be to take Sk to be the smallest
;initial subset of height k, and take Ik to be Sk-S(k-1).
;But this does not work:
;(xy-uv), (y), (u,x), (v)

;I don't have such an example for ideals generated by 
;monomials at the moment (5/15/90).  But with monomials you might hope
;in addition that you could just take the sum of the elements
;in each ideal.
;But this does not work:
;(ab,ac), (bc,ad), (bd,cd)
;however, random elements from each ideal do the trick
;in this case:
<ring 4 a-d r
<ideal i1 ab ac
<ideal i2 bc ad
<ideal i3 bd cd
<random_mat 1 1 i1 f1
<random_mat 1 1 i2 f2
<random_mat 1 1 i3 f3
copy f1 f
concat f f2
concat f f3
std f f
codim f ;shows f is a regular sequence


<ring 4 a-z r
power r 4 r4
std r4 r4

<random_mat 1 3 r4 f
<random_mat 1 1 r4 g
set timer 1
quotient f g h

std f f
qring f q
fetch g g
<ideal zero
quotient zero g h


