incr-set prlevel 1
if #0=2 START
incr-set prlevel -1
;;; Usage:
;;; 	<regular_sequence i reg
;;;
;;; a very 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.
;;; Find the smallest initial subset I3 of height 
;;; bigger than whats been done so far, drop the first
;;; k elements and 
;;; define the k+1 st element of f to be a 
;;; random linear combination of the elements of I2
;;;  (This version does not use reduction mod
;;; the regular sequence, etc.  It seems slightly
;;; faster than "regular_sequence1" in some examples.)
;;; Caveats:  Still very slow.  There must be 
;;; some way to be cleverer about this.
;;;
; 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
int @pointer 1 ;last place used in the f's	

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

;Find an initial subset of @i with codimension @n.

	loop:
	int @pointer @pointer+1
	submat @i @j
		;
		1..@pointer
	std @j @j
	codim @j @codimj
	if @codimj=@n 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. However,
;because the first @n-1 elements have been used,
;we don't need to consider them:
submat @j @j
	;
	@n..@pointer
transpose @j @j'
min @j' @jmax
int @jmax -@jmax
<random_element @j @jmax @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


