| [1201] | 1 | ;;; -*-  Mode: Lisp -*- 
 | 
|---|
| [302] | 2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
|---|
 | 3 | ;;;                                                                              
 | 
|---|
 | 4 | ;;;  Copyright (C) 1999, 2002, 2009, 2015 Marek Rychlik <rychlik@u.arizona.edu>          
 | 
|---|
 | 5 | ;;;                                                                              
 | 
|---|
 | 6 | ;;;  This program is free software; you can redistribute it and/or modify        
 | 
|---|
 | 7 | ;;;  it under the terms of the GNU General Public License as published by        
 | 
|---|
 | 8 | ;;;  the Free Software Foundation; either version 2 of the License, or           
 | 
|---|
 | 9 | ;;;  (at your option) any later version.                                         
 | 
|---|
 | 10 | ;;;                                                                              
 | 
|---|
 | 11 | ;;;  This program is distributed in the hope that it will be useful,             
 | 
|---|
 | 12 | ;;;  but WITHOUT ANY WARRANTY; without even the implied warranty of              
 | 
|---|
 | 13 | ;;;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               
 | 
|---|
 | 14 | ;;;  GNU General Public License for more details.                                
 | 
|---|
 | 15 | ;;;                                                                              
 | 
|---|
 | 16 | ;;;  You should have received a copy of the GNU General Public License           
 | 
|---|
 | 17 | ;;;  along with this program; if not, write to the Free Software                 
 | 
|---|
 | 18 | ;;;  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
 | 
|---|
 | 19 | ;;;                                                                              
 | 
|---|
 | 20 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
|---|
 | 21 | 
 | 
|---|
| [309] | 22 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
|---|
 | 23 | ;;
 | 
|---|
| [355] | 24 | ;; Run tests using 5am unit testing framework
 | 
|---|
| [309] | 25 | ;;
 | 
|---|
 | 26 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
|---|
 | 27 | 
 | 
|---|
| [342] | 28 | ;; We assume that QuickLisp package manager is installed.
 | 
|---|
 | 29 | ;; See :
 | 
|---|
 | 30 | ;;      https://www.quicklisp.org/beta/
 | 
|---|
 | 31 | ;;
 | 
|---|
 | 32 | 
 | 
|---|
 | 33 | ;; The following is unnecessary after running:
 | 
|---|
 | 34 | ;; * (ql:add-to-init-file)
 | 
|---|
 | 35 | ;; at lisp prompt:
 | 
|---|
 | 36 | ;;(load "~/quicklisp/setup")
 | 
|---|
 | 37 | 
 | 
|---|
| [286] | 38 | (ql:quickload :fiveam)
 | 
|---|
| [301] | 39 | 
 | 
|---|
| [292] | 40 | (load "ngrobner.asd")
 | 
|---|
| [291] | 41 | (asdf:load-system :ngrobner)
 | 
|---|
| [1326] | 42 | 
 | 
|---|
| [367] | 43 | (defpackage #:ngrobner-tests
 | 
|---|
| [604] | 44 |   (:use :cl :it.bese.fiveam 
 | 
|---|
| [1612] | 45 |         :ngrobner :priority-queue :monom
 | 
|---|
| [957] | 46 |         :utils :order :ring :term :ring-and-order 
 | 
|---|
| [1069] | 47 |         :termlist :polynomial
 | 
|---|
| [1024] | 48 |         :priority-queue 
 | 
|---|
| [1175] | 49 |         :division
 | 
|---|
| [1364] | 50 |         :grobner-wrap
 | 
|---|
| [604] | 51 |         )
 | 
|---|
 | 52 |   )
 | 
|---|
| [286] | 53 | 
 | 
|---|
| [1251] | 54 | (in-package :ngrobner-tests)
 | 
|---|
| [287] | 55 | 
 | 
|---|
| [367] | 56 | (def-suite ngrobner-suite 
 | 
|---|
| [368] | 57 |     :description "New Groebner Package Suite")
 | 
|---|
| [281] | 58 | 
 | 
|---|
| [367] | 59 | (in-suite ngrobner-suite)
 | 
|---|
| [287] | 60 | 
 | 
|---|
| [312] | 61 | #+nil
 | 
|---|
| [289] | 62 | (test dummy-test
 | 
|---|
| [281] | 63 |   "Makelist"
 | 
|---|
 | 64 |   (is (= (+ 2 2)) "2 plus 2 wasn't equal to 4 (using #'= to test equality)")
 | 
|---|
 | 65 |   (is (= 0 (+ -1 1)))
 | 
|---|
 | 66 |   (signals
 | 
|---|
 | 67 |       (error "Trying to add 4 to FOO didn't signal an error")
 | 
|---|
 | 68 |     (+ 'foo 4))
 | 
|---|
 | 69 |   (is (= 0 (+ 1 1)) "this should have failed"))
 | 
|---|
| [289] | 70 | 
 | 
|---|
| [293] | 71 | (test makelist-1 
 | 
|---|
| [303] | 72 |   "makelist-1 test"
 | 
|---|
| [597] | 73 |   (is (equal (makelist-1 (* 2 i) i 0 10) '(0 2 4 6 8 10 12 14 16 18 20)))
 | 
|---|
 | 74 |   (is (equal (makelist-1 (* 2 i) i 0 10 3) '(0 6 12 18))))
 | 
|---|
| [294] | 75 | 
 | 
|---|
| [303] | 76 | (test makelist
 | 
|---|
| [314] | 77 |   "makelist"
 | 
|---|
| [598] | 78 |   (is (equal (makelist (+ (* i i) (* j j)) (i 1 4) (j 1 i)) '(2 5 8 10 13 18 17 20 25 32)))
 | 
|---|
 | 79 |   (is (equal (makelist (list i j '---> (+ (* i i) (* j j))) (i 1 4) (j 1 i))
 | 
|---|
| [303] | 80 |              '((1 1 ---> 2) (2 1 ---> 5) (2 2 ---> 8) (3 1 ---> 10) (3 2 ---> 13)
 | 
|---|
 | 81 |                (3 3 ---> 18) (4 1 ---> 17) (4 2 ---> 20) (4 3 ---> 25) (4 4 ---> 32)))))
 | 
|---|
| [290] | 82 | 
 | 
|---|
| [1414] | 83 | (test summation
 | 
|---|
 | 84 |   "summation"
 | 
|---|
 | 85 |   (is (= (summation i (i 0 100)) 5050)))
 | 
|---|
 | 86 | 
 | 
|---|
| [1415] | 87 | (test inner-product
 | 
|---|
 | 88 |   "summation"
 | 
|---|
 | 89 |   (is (= (inner-product '(1 2 3) '(4 5 6)) 32)))
 | 
|---|
 | 90 | 
 | 
|---|
| [314] | 91 | (test monom
 | 
|---|
 | 92 |   "monom"
 | 
|---|
| [885] | 93 |   (is (every #'= (make-monom :dimension 3) '(0 0 0)) "Trivial monomial is a vector of 0's")
 | 
|---|
 | 94 |   (is (every #'= (make-monom :initial-exponents '(1 2 3)) '(1 2 3)) "Monomial with powers 1,2,3")
 | 
|---|
| [867] | 95 |   (let ((p (make-monom :initial-exponents '(1 2 3))))
 | 
|---|
| [885] | 96 |     (is (every #'= (monom-map (lambda (x) x) p) '(1 2 3)))))
 | 
|---|
| [867] | 97 | 
 | 
|---|
| [303] | 98 |   
 | 
|---|
| [347] | 99 | (test order
 | 
|---|
 | 100 |   "order"
 | 
|---|
| [948] | 101 |   (let ((p (make-monom :initial-exponents '(1 3 2)))
 | 
|---|
 | 102 |         (q (make-monom :initial-exponents '(1 2 3))))
 | 
|---|
| [600] | 103 |     (is-true (lex>  p q)) 
 | 
|---|
 | 104 |     (is-true (grlex>  p q)) 
 | 
|---|
 | 105 |     (is-true (revlex>  p q)) 
 | 
|---|
 | 106 |     (is-true (grevlex>  p q)) 
 | 
|---|
| [948] | 107 |     (is-false (invlex>  p q))))
 | 
|---|
 | 108 | 
 | 
|---|
 | 109 | (test elim-order
 | 
|---|
 | 110 |   "elimination order"
 | 
|---|
 | 111 |   (let* ((p (make-monom :initial-exponents '(1 2 3)))
 | 
|---|
 | 112 |          (q (make-monom :initial-exponents '(4 5 6)))
 | 
|---|
 | 113 |          (elim-order-factory (make-elimination-order-factory))
 | 
|---|
 | 114 |          (elim-order-1 (funcall elim-order-factory 1))
 | 
|---|
 | 115 |          (elim-order-2 (funcall elim-order-factory 2)))
 | 
|---|
| [949] | 116 |     (is-false (funcall elim-order-1 p q))
 | 
|---|
 | 117 |     (is-false (funcall elim-order-2 p q))))
 | 
|---|
| [347] | 118 | 
 | 
|---|
| [381] | 119 | (test term
 | 
|---|
 | 120 |   "term"
 | 
|---|
| [855] | 121 |   (let* ((m1 (make-monom :initial-exponents '(1 2 3)))
 | 
|---|
 | 122 |          (m2 (make-monom :initial-exponents '(3 5 2)))
 | 
|---|
| [602] | 123 |          (m3 (monom-mul m1 m2))
 | 
|---|
| [1854] | 124 |          (t1 (make-term :monom m1 :coeff 7))
 | 
|---|
 | 125 |          (t2 (make-term :monom m2 :coeff 9))
 | 
|---|
 | 126 |          (t3 (make-term :monom m3 :coeff (* 7 9))))
 | 
|---|
| [1665] | 127 |     (is (equalp (term-mul +ring-of-integers+ t1 t2) t3))))
 | 
|---|
| [381] | 128 | 
 | 
|---|
| [950] | 129 | (test termlist
 | 
|---|
 | 130 |   "termlist"
 | 
|---|
| [1855] | 131 |   (let* ((t1 (make-term  :monom (make-monom :initial-exponents '(1 2 3)) :coeff 7))
 | 
|---|
 | 132 |          (t2 (make-term  :monom (make-monom :initial-exponents '(3 5 2)) :coeff 9))
 | 
|---|
 | 133 |          (t11 (make-term :monom (make-monom :initial-exponents '(2 4 6)) :coeff 49))
 | 
|---|
 | 134 |          (t12 (make-term :monom (make-monom :initial-exponents '(4 7 5)) :coeff 126))
 | 
|---|
 | 135 |          (t22 (make-term :monom (make-monom :initial-exponents '(6 10 4)) :coeff 81))
 | 
|---|
| [963] | 136 |          (p (list t2 t1))
 | 
|---|
 | 137 |          (p-sq (list t22 t12 t11))
 | 
|---|
| [956] | 138 |          (ring-and-order (make-ring-and-order))
 | 
|---|
 | 139 |          (q (termlist-expt ring-and-order p 2)))
 | 
|---|
| [969] | 140 |     (is-true (equalp q p-sq))))
 | 
|---|
| [950] | 141 | 
 | 
|---|
| [970] | 142 | (test poly
 | 
|---|
 | 143 |   "poly"
 | 
|---|
| [1856] | 144 |   (let* ((t1 (make-term  :monom (make-monom :initial-exponents '(1 2 3)) :coeff 7))
 | 
|---|
 | 145 |          (t2 (make-term  :monom (make-monom :initial-exponents '(3 5 2)) :coeff 9))
 | 
|---|
 | 146 |          (t11 (make-term :monom (make-monom :initial-exponents '(2 4 6)) :coeff 49))
 | 
|---|
 | 147 |          (t12 (make-term :monom (make-monom :initial-exponents '(4 7 5)) :coeff 126))
 | 
|---|
 | 148 |          (t22 (make-term :monom (make-monom :initial-exponents '(6 10 4)) :coeff 81))
 | 
|---|
| [970] | 149 |          (p (make-poly-from-termlist (list t2 t1)))
 | 
|---|
 | 150 |          (p-sq (make-poly-from-termlist (list t22 t12 t11)))
 | 
|---|
 | 151 |          (ring-and-order (make-ring-and-order))
 | 
|---|
| [1027] | 152 |          (q (poly-expt ring-and-order p 2)))
 | 
|---|
| [972] | 153 |     (is-true (equalp q p-sq))))
 | 
|---|
| [950] | 154 | 
 | 
|---|
 | 155 | 
 | 
|---|
| [381] | 156 | (test coerce-to-infix
 | 
|---|
| [582] | 157 |   "Conversion to infix form"
 | 
|---|
 | 158 |   (is (equal 
 | 
|---|
| [1665] | 159 |        (coerce-to-infix :term (make-term-variable +ring-of-integers+ 5 3) '(x y z w u v))
 | 
|---|
| [582] | 160 |        '(* 1 (EXPT X 0) (EXPT Y 0) (EXPT Z 0) (EXPT W 1) (EXPT U 0)))))
 | 
|---|
| [381] | 161 | 
 | 
|---|
| [584] | 162 | (test priority-queue
 | 
|---|
 | 163 |   "Priority queue"
 | 
|---|
| [607] | 164 |   (let ((q (make-priority-queue)))
 | 
|---|
 | 165 |     (priority-queue-insert q 7)
 | 
|---|
 | 166 |     (priority-queue-insert q 8)
 | 
|---|
 | 167 |     (is (= (priority-queue-size q) 3) "Note that there is always a dummy element in the queue.")
 | 
|---|
 | 168 |     (is (equalp (priority-queue-heap q) #(0 7 8)))
 | 
|---|
 | 169 |     (is (= (priority-queue-remove q) 7))
 | 
|---|
 | 170 |     (is (= (priority-queue-remove q) 8))
 | 
|---|
| [610] | 171 |     (is-true (priority-queue-empty-p q))
 | 
|---|
| [613] | 172 |     (signals
 | 
|---|
 | 173 |         (error "Empty queue.")
 | 
|---|
 | 174 |       (priority-queue-remove q))))
 | 
|---|
| [584] | 175 | 
 | 
|---|
| [634] | 176 | ;;
 | 
|---|
 | 177 | ;; Currently parser cannot be tested, as it relies on many maxima functions
 | 
|---|
 | 178 | ;; to parse a polynomial expression.
 | 
|---|
 | 179 | ;;
 | 
|---|
| [614] | 180 | #|
 | 
|---|
 | 181 | (test parser
 | 
|---|
 | 182 |   "Parser"
 | 
|---|
 | 183 |   (let (($f '((MLIST SIMP) ((MPLUS SIMP) $X ((MTIMES SIMP) -1 $Y)) ((MPLUS SIMP) $X $Y)))
 | 
|---|
| [620] | 184 |         ($v '((MLIST SIMP) $X $Y)))
 | 
|---|
 | 185 |     (is-true (parse-poly-list $f $v))))
 | 
|---|
| [633] | 186 | |#
 | 
|---|
| [614] | 187 | 
 | 
|---|
| [691] | 188 | (test infix-print 
 | 
|---|
| [694] | 189 |   "Infix printer"
 | 
|---|
| [691] | 190 |   (is (string= (infix-print '(+ x y) nil) "X+Y"))
 | 
|---|
 | 191 |   (is (string= (infix-print '(expt x 3) nil) "X^3"))
 | 
|---|
| [693] | 192 |   (is (string= (infix-print '(+ 1 (expt x 3)) nil) "1+(X^3)"))
 | 
|---|
 | 193 |   (is (string= (infix-print '(* x y) nil) "X*Y"))
 | 
|---|
 | 194 |   (is (string= (infix-print '(* x (expt y 2)) nil) "X*(Y^2)")))
 | 
|---|
| [832] | 195 | 
 | 
|---|
 | 196 | (test infix
 | 
|---|
 | 197 |   "Infix parser"
 | 
|---|
| [693] | 198 |   (is (equal '#I( x^2 + y^2 ) '(+ (expt x 2) (expt y 2))))
 | 
|---|
| [831] | 199 |   (is (equal '#I( [ x, y ] ) '(:[ X Y)))
 | 
|---|
 | 200 |   (is (equal '#I( x + y) '(+ x y)))
 | 
|---|
| [864] | 201 |   (is (equal '#I( x^3 ) '(expt x 3)))
 | 
|---|
 | 202 |   (is (equal '#I( 1 + x^3) '(+ 1 (expt x 3))))
 | 
|---|
 | 203 |   (is (equal '#I( x * y^2 ) '(* x (expt y 2)))))
 | 
|---|
| [691] | 204 | 
 | 
|---|
| [1070] | 205 | (test poly-reader
 | 
|---|
 | 206 |   "Polynomial reader"
 | 
|---|
| [1084] | 207 |   (is (equalp (with-input-from-string (s "X^2-Y^2+(-4/3)*U^2*W^3-5")
 | 
|---|
| [1089] | 208 |                 (read-infix-form :stream s))
 | 
|---|
| [1083] | 209 |               '(+ (- (EXPT X 2) (EXPT Y 2)) (* (- (/ 4 3)) (EXPT U 2) (EXPT W 3)) (- 5))))
 | 
|---|
| [1167] | 210 |   (is (equalp (string->alist "X^2-Y^2+(-4/3)*U^2*W^3-5" '(x y u w))
 | 
|---|
 | 211 |               '(((2 0 0 0) . 1)
 | 
|---|
 | 212 |                 ((0 2 0 0) . -1) 
 | 
|---|
 | 213 |                 ((0 0 2 3) . -4/3)
 | 
|---|
 | 214 |                 ((0 0 0 0) . -5))))
 | 
|---|
| [1173] | 215 |   (is (equalp (string->alist "[x^2-y^2+(-4/3)*u^2*w^3-5,y]" '(x y u w))
 | 
|---|
 | 216 |               '(:[ 
 | 
|---|
 | 217 |                 (((2 0 0 0) . 1) ((0 2 0 0) . -1) ((0 0 2 3) . -4/3) ((0 0 0 0) . -5))
 | 
|---|
 | 218 |                 (((0 1 0 0) . 1)))))
 | 
|---|
| [1857] | 219 |   (let ((p (make-poly-from-termlist (list (make-term :monom (make-monom :initial-exponents '(2 0)) :coeff 1)
 | 
|---|
 | 220 |                                           (make-term :monom (make-monom :initial-exponents '(0 2)) :coeff 2)))))
 | 
|---|
| [1101] | 221 |     (is (equalp (with-input-from-string (s "x^2+2*y^2") 
 | 
|---|
 | 222 |                   (read-poly '(x y) :stream s))
 | 
|---|
 | 223 |                 p))
 | 
|---|
| [1103] | 224 |     (is (equalp (string->poly "x^2+2*y^2" '(x y)) p))))
 | 
|---|
| [1023] | 225 | 
 | 
|---|
| [1223] | 226 | ;; Manual calculation supporting the test below.
 | 
|---|
 | 227 | ;; We divide X^2 by [X+Y,X-2*Y] with LEX> as order.
 | 
|---|
 | 228 | ;; LM(X^2)=X^2 is divisible by LM(X+Y)=X so the first partial quotient is X.
 | 
|---|
 | 229 | ;; Next, X^2 - X*(X+Y) = -X*Y.
 | 
|---|
| [1224] | 230 | ;; LM(-X*Y)=X*Y is divibile by LM(X+Y)=X so the second partial quotient is -Y.
 | 
|---|
| [1281] | 231 | ;; Next, -X*Y-(-Y)*(X+Y) = Y^2.
 | 
|---|
 | 232 | ;; LM(Y^2)=Y^2 is not divisible by LM(X+Y)=X or LM(X-2*Y)=X. Hence, division
 | 
|---|
 | 233 | ;; ends. The list of quotients is [X-Y,0]. The remainder is Y^2
 | 
|---|
| [1174] | 234 | (test division
 | 
|---|
 | 235 |   "Division in polynomial ring"
 | 
|---|
| [1183] | 236 |   (let* ((f (string->poly "x^2" '(x y)))
 | 
|---|
| [1186] | 237 |          (y-sq (string->poly "y^2" '(x y)))
 | 
|---|
| [1183] | 238 |          (fl (cdr (string->poly "[x+y,x-2*y]" '(x y))))
 | 
|---|
| [1665] | 239 |          (ring +ring-of-integers+)
 | 
|---|
| [1183] | 240 |          (order #'lex>)
 | 
|---|
| [1194] | 241 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
 | 242 |          (quotients (cdr (string->poly "[x-y,0]" '(x y)))))
 | 
|---|
| [1250] | 243 |     (is (equalp (multiple-value-list (normal-form ring-and-order f fl)) (list y-sq 1 2)))
 | 
|---|
| [1196] | 244 |     (is (equalp (multiple-value-list (poly-pseudo-divide ring-and-order f fl))
 | 
|---|
| [1202] | 245 |                 (list quotients y-sq 1 2)))
 | 
|---|
| [1283] | 246 |     (is-false (buchberger-criterion ring-and-order fl)))
 | 
|---|
| [1287] | 247 |   (let* ((f (string->poly "x^2-4*y^2" '(x y)))
 | 
|---|
 | 248 |          (g (string->poly "x+2*y" '(x y)))
 | 
|---|
 | 249 |          (h (string->poly "x-2*y" '(x y)))
 | 
|---|
| [1665] | 250 |          (ring +ring-of-integers+)
 | 
|---|
| [1286] | 251 |          (order #'lex>)
 | 
|---|
 | 252 |          (ring-and-order (make-ring-and-order :ring ring :order order)))
 | 
|---|
| [1449] | 253 |     (is (poly-equal-no-sugar-p (poly-exact-divide ring-and-order f g) h))))
 | 
|---|
| [1174] | 254 | 
 | 
|---|
| [1303] | 255 | 
 | 
|---|
 | 256 | (test buchberger
 | 
|---|
 | 257 |   "Buchberger algorithm"
 | 
|---|
 | 258 |   (let* ((fl (cdr (string->poly "[x+y,x-2*y]" '(x y))))
 | 
|---|
| [1665] | 259 |          (ring +ring-of-integers+)
 | 
|---|
| [1303] | 260 |          (order #'lex>)
 | 
|---|
 | 261 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
| [1306] | 262 |          (gb (cdr (string->poly "[x+y,x-2*y,y]" '(x y)))))
 | 
|---|
| [1324] | 263 |     (is-true (grobner-test ring-and-order gb fl))
 | 
|---|
| [1448] | 264 |     (is (every #'poly-equal-no-sugar-p (buchberger ring-and-order fl) gb))
 | 
|---|
 | 265 |     (is (every #'poly-equal-no-sugar-p (parallel-buchberger ring-and-order fl) gb))))
 | 
|---|
| [1303] | 266 | 
 | 
|---|
| [1318] | 267 | (test gebauer-moeller
 | 
|---|
 | 268 |   "Gebauer-Moeller algorithm"
 | 
|---|
 | 269 |   (let* ((fl (cdr (string->poly "[x+y,x-2*y]" '(x y))))
 | 
|---|
| [1665] | 270 |          (ring +ring-of-integers+)
 | 
|---|
| [1318] | 271 |          (order #'lex>)
 | 
|---|
 | 272 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
| [1322] | 273 |          (gb (cdr (string->poly "[y,x-2*y]" '(x y)))))
 | 
|---|
| [1324] | 274 |     (is-true (grobner-test ring-and-order gb fl))
 | 
|---|
| [1447] | 275 |     (is (every #'poly-equal-no-sugar-p (gebauer-moeller ring-and-order fl) gb))))
 | 
|---|
| [1303] | 276 | 
 | 
|---|
| [1548] | 277 | (test reduction
 | 
|---|
 | 278 |   "Reduction algorithm"
 | 
|---|
| [1550] | 279 |   (let* ((fl (cdr (string->poly "[x^2,x+y,x-2*y]" '(x y))))
 | 
|---|
| [1665] | 280 |          (ring +ring-of-integers+)
 | 
|---|
| [1336] | 281 |          (order #'lex>)
 | 
|---|
 | 282 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
| [1337] | 283 |          (gb (cdr (string->poly "[y,x-2*y]" '(x y))))
 | 
|---|
| [1339] | 284 |          (reduced-gb (cdr (string->poly "[y,x]" '(x y)))))
 | 
|---|
| [1336] | 285 |     (is-true (grobner-test ring-and-order gb fl))
 | 
|---|
| [1567] | 286 |     (is (poly-set-equal-no-sugar-p (reduction ring-and-order gb) reduced-gb))))
 | 
|---|
| [1303] | 287 | 
 | 
|---|
| [1548] | 288 | (test minimization
 | 
|---|
 | 289 |   "Minimization algorithm"
 | 
|---|
 | 290 |   (let* ((gb (cdr (string->poly "[x,y,x-2*y,x^2]" '(x y))))
 | 
|---|
 | 291 |          (minimal-gb (cdr (string->poly "[y,x-2*y]" '(x y)))))
 | 
|---|
 | 292 |     (is (equalp (minimization gb) minimal-gb))))
 | 
|---|
 | 293 | 
 | 
|---|
| [1365] | 294 | (test grobner-wrap
 | 
|---|
| [1366] | 295 |   "Grobner interface to many algorithms"
 | 
|---|
| [1368] | 296 |   (let* (($poly_grobner_algorithm :buchberger)
 | 
|---|
| [1367] | 297 |          (fl (cdr (string->poly "[x+y,x-2*y]" '(x y))))
 | 
|---|
| [1665] | 298 |          (ring +ring-of-integers+)
 | 
|---|
| [1365] | 299 |          (order #'lex>)
 | 
|---|
 | 300 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
| [1371] | 301 |          (gb (cdr (string->poly "[x+y,x-2*y,y]" '(x y))))
 | 
|---|
| [1372] | 302 |          (reduced-gb (cdr (string->poly "[y,x]" '(x y)))))
 | 
|---|
| [1365] | 303 |     (is-true (grobner-test ring-and-order gb fl))
 | 
|---|
| [1562] | 304 |     (is (poly-set-equal-no-sugar-p (grobner ring-and-order fl) gb))
 | 
|---|
 | 305 |     (is (poly-set-equal-no-sugar-p (reduced-grobner ring-and-order fl) reduced-gb))))
 | 
|---|
| [1336] | 306 | 
 | 
|---|
| [1562] | 307 | 
 | 
|---|
| [1422] | 308 | (test elimination-ideal
 | 
|---|
 | 309 |   "Elimination ideal"
 | 
|---|
| [1417] | 310 |   (let* (($poly_grobner_algorithm :buchberger)
 | 
|---|
 | 311 |          (fl (cdr (string->poly "[x+y,x-2*y]" '(x y))))
 | 
|---|
| [1665] | 312 |          (ring +ring-of-integers+)
 | 
|---|
| [1417] | 313 |          (order #'lex>)
 | 
|---|
| [1418] | 314 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
| [1419] | 315 |          (elim-1-fl (cdr (string->poly "[y]" '(x y)))))
 | 
|---|
| [1562] | 316 |     (is (poly-set-equal-no-sugar-p (elimination-ideal ring-and-order fl 1) elim-1-fl))
 | 
|---|
| [1563] | 317 |     (is (null (elimination-ideal ring-and-order fl 2)))))
 | 
|---|
| [1416] | 318 | 
 | 
|---|
| [1425] | 319 | (test colon-ideal
 | 
|---|
| [1434] | 320 |   "Colon ideal"
 | 
|---|
| [1425] | 321 |   (let* (($poly_grobner_algorithm :buchberger)
 | 
|---|
 | 322 |          (I (cdr (string->poly "[x^2*y,x*y^2]" '(x y))))
 | 
|---|
 | 323 |          (J (cdr (string->poly "[x,y]" '(x y))))
 | 
|---|
| [1665] | 324 |          (ring +ring-of-integers+)
 | 
|---|
| [1425] | 325 |          (order #'lex>)
 | 
|---|
 | 326 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
| [1438] | 327 |          (I-colon-J (cdr (string->poly "[x*y]" '(x y)))))
 | 
|---|
| [1564] | 328 |     (is (poly-set-equal-no-sugar-p (colon-ideal ring-and-order I J) I-colon-J))))
 | 
|---|
| [1425] | 329 | 
 | 
|---|
| [1457] | 330 | (test poly-lcm
 | 
|---|
 | 331 |   "Polynomial LCM"
 | 
|---|
| [1450] | 332 |   (let* (($poly_grobner_algorithm :buchberger)
 | 
|---|
| [1451] | 333 |          (f (string->poly "x^2-y^2" '(x y)))
 | 
|---|
| [1458] | 334 |          (g (string->poly "(x+y)^2" '(x y)))
 | 
|---|
| [1665] | 335 |          (ring +ring-of-integers+)
 | 
|---|
| [1450] | 336 |          (order #'lex>)
 | 
|---|
 | 337 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
| [1457] | 338 |          (lcm-f-and-g (string->poly "(x+y)^2*(x-y)" '(x y))))
 | 
|---|
 | 339 |     (is (poly-equal-no-sugar-p (poly-lcm ring-and-order f g) lcm-f-and-g))))
 | 
|---|
| [1437] | 340 | 
 | 
|---|
| [1460] | 341 | (test grobner-member
 | 
|---|
| [1461] | 342 |   "Ideal membership"
 | 
|---|
| [1460] | 343 |   (let* (($poly_grobner_algorithm :buchberger)
 | 
|---|
 | 344 |          (f (string->poly "y" '(x y)))
 | 
|---|
| [1464] | 345 |          (fl (cdr (string->poly "[x-y,x+y,y]" '(x y))))
 | 
|---|
| [1665] | 346 |          (ring +ring-of-integers+)
 | 
|---|
| [1460] | 347 |          (order #'lex>)
 | 
|---|
 | 348 |          (ring-and-order (make-ring-and-order :ring ring :order order)))
 | 
|---|
| [1463] | 349 |     (is-true (buchberger-criterion ring-and-order fl))
 | 
|---|
| [1461] | 350 |     (is-true (grobner-member ring-and-order f fl))))
 | 
|---|
| [1460] | 351 | 
 | 
|---|
| [1459] | 352 | (test grobner-equal
 | 
|---|
| [1465] | 353 |   "Equality of ideal generated by Groebner bases"
 | 
|---|
| [1459] | 354 |   (let* (($poly_grobner_algorithm :buchberger)
 | 
|---|
| [1466] | 355 |          (fl (cdr (string->poly "[x,x-y,y]" '(x y))))
 | 
|---|
 | 356 |          (gl (cdr (string->poly "[x-y,x+2*y,y]" '(x y))))
 | 
|---|
| [1665] | 357 |          (ring +ring-of-integers+)
 | 
|---|
| [1459] | 358 |          (order #'lex>)
 | 
|---|
 | 359 |          (ring-and-order (make-ring-and-order :ring ring :order order)))
 | 
|---|
| [1465] | 360 |     (is-true (buchberger-criterion ring-and-order fl))
 | 
|---|
 | 361 |     (is-true (buchberger-criterion ring-and-order gl))
 | 
|---|
 | 362 |     (is-true (grobner-equal ring-and-order fl gl))))
 | 
|---|
| [1450] | 363 | 
 | 
|---|
| [1498] | 364 | ;; Calculates [F, U*P-1]
 | 
|---|
| [1496] | 365 | (test saturation-extension-1
 | 
|---|
| [1489] | 366 |   "Saturation extension with 1 polynomial"
 | 
|---|
| [1482] | 367 |   (let* ((F-str "[x^3,x^2*y]")
 | 
|---|
 | 368 |          (F (cdr (string->poly F-str '(x y))))
 | 
|---|
| [1478] | 369 |          (P (string->poly "x^2" '(x y)))
 | 
|---|
| [1665] | 370 |          (ring +ring-of-integers+)
 | 
|---|
| [1498] | 371 |          (F-sat (append (cdr (string->poly F-str '(u x y)))
 | 
|---|
 | 372 |                         (cdr (string->poly "[u*x^2-1]" '(u x y))))))
 | 
|---|
| [1565] | 373 |     (is (poly-set-equal-no-sugar-p   (saturation-extension-1 ring F p) F-sat))))
 | 
|---|
| [1496] | 374 | 
 | 
|---|
| [1505] | 375 | ;; Calculate [F, U1*P1+U2*P2+...+UK*PK-1], where PLIST=[P1,P2,...,PK]. It destructively modifies F.
 | 
|---|
| [1499] | 376 | (test polysaturation-extension
 | 
|---|
| [1501] | 377 |   "Polysaturation extension"
 | 
|---|
| [1496] | 378 |   (let* ((F-str "[x^3,x^2*y]")
 | 
|---|
 | 379 |          (F (cdr (string->poly F-str '(x y))))
 | 
|---|
| [1498] | 380 |          (P (cdr (string->poly "[x^2,x*y]" '(x y))))
 | 
|---|
| [1665] | 381 |          (ring +ring-of-integers+)
 | 
|---|
| [1502] | 382 |          (F-sat (append (cdr (string->poly F-str '(u1 u2 x y)))
 | 
|---|
| [1505] | 383 |                         (cdr (string->poly "[u1*(x^2) + u2*(x*y)-1]" '(u1 u2 x y))))))
 | 
|---|
| [1565] | 384 |     (is (poly-set-equal-no-sugar-p (polysaturation-extension ring F P) F-sat))))
 | 
|---|
| [1478] | 385 | 
 | 
|---|
| [1531] | 386 | ;; Calculate F : p^inf
 | 
|---|
| [1467] | 387 | (test ideal-saturation-1
 | 
|---|
| [1508] | 388 |   "Ideal saturation with 1 polynomial"
 | 
|---|
| [1536] | 389 |   (let* (($poly_grobner_algorithm :buchberger)
 | 
|---|
| [1576] | 390 |          (F (cdr (string->poly "[x^3*(y+z^2),x^2*(y-z^2)]" '(x y z))))
 | 
|---|
| [1572] | 391 |          (p (string->poly "x" '(x y z)))
 | 
|---|
| [1665] | 392 |          (ring +ring-of-integers+)
 | 
|---|
| [1467] | 393 |          (order #'lex>)
 | 
|---|
| [1574] | 394 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
| [1577] | 395 |          (G (cdr (string->poly "[y,z^2]" '(x y z)))))
 | 
|---|
| [1574] | 396 |     (is (poly-set-equal-no-sugar-p (ideal-saturation-1 ring-and-order F p) G))))
 | 
|---|
| [1459] | 397 | 
 | 
|---|
| [1578] | 398 | ;; Calculate F : p1^inf : p2^inf : ... : ps^inf
 | 
|---|
 | 399 | (test ideal-polysaturation-1
 | 
|---|
| [1580] | 400 |   "Ideal polysaturation one-by-one with 2 polynomials"
 | 
|---|
| [1578] | 401 |   (let* (($poly_grobner_algorithm :buchberger)
 | 
|---|
| [1583] | 402 |          (F (cdr (string->poly "[x^3*z*y,x*z*y^2]" '(x y z))))
 | 
|---|
| [1581] | 403 |          (P (cdr (string->poly "[x,z]" '(x y z))))
 | 
|---|
| [1665] | 404 |          (ring +ring-of-integers+)
 | 
|---|
| [1578] | 405 |          (order #'lex>)
 | 
|---|
 | 406 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
| [1582] | 407 |          (G (cdr (string->poly "[y]" '(x y z)))))
 | 
|---|
| [1585] | 408 |     (is (poly-set-equal-no-sugar-p (ideal-polysaturation-1 ring-and-order F p) G))))
 | 
|---|
| [1578] | 409 | 
 | 
|---|
| [1586] | 410 | ;; Calculate F : P^inf
 | 
|---|
 | 411 | (test ideal-saturation
 | 
|---|
 | 412 |   "Ideal saturation"
 | 
|---|
 | 413 |   (let* (($poly_grobner_algorithm :buchberger)
 | 
|---|
 | 414 |          (F (cdr (string->poly "[x^3*(y+z^2),x^2*(y-z^2)]" '(x y z))))
 | 
|---|
| [1587] | 415 |          (P (cdr (string->poly "[x]" '(x y z))))
 | 
|---|
| [1665] | 416 |          (ring +ring-of-integers+)
 | 
|---|
| [1586] | 417 |          (order #'lex>)
 | 
|---|
 | 418 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
 | 419 |          (G (cdr (string->poly "[y,z^2]" '(x y z)))))
 | 
|---|
 | 420 |     (is (poly-set-equal-no-sugar-p (ideal-saturation ring-and-order F P) G))))
 | 
|---|
 | 421 | 
 | 
|---|
| [1589] | 422 | ;; Calculate F : P1^inf : P2^inf : ... : Ps^inf where Pi are ideals
 | 
|---|
 | 423 | (test ideal-polysaturation
 | 
|---|
 | 424 |   "Ideal polysaturation"
 | 
|---|
| [1586] | 425 |   (let* (($poly_grobner_algorithm :buchberger)
 | 
|---|
 | 426 |          (F (cdr (string->poly "[x^3*z*y,x*z*y^2]" '(x y z))))
 | 
|---|
| [1589] | 427 |          (P1 (cdr (string->poly "[x]" '(x y z))))
 | 
|---|
 | 428 |          (P2 (cdr (string->poly "[z]" '(x y z))))
 | 
|---|
| [1665] | 429 |          (ring +ring-of-integers+)
 | 
|---|
| [1586] | 430 |          (order #'lex>)
 | 
|---|
 | 431 |          (ring-and-order (make-ring-and-order :ring ring :order order))
 | 
|---|
 | 432 |          (G (cdr (string->poly "[y]" '(x y z)))))
 | 
|---|
| [1591] | 433 |     (is (poly-set-equal-no-sugar-p (ideal-polysaturation ring-and-order F (list P1 P2)) G))))
 | 
|---|
| [1586] | 434 | 
 | 
|---|
| [367] | 435 | (run! 'ngrobner-suite)
 | 
|---|
| [346] | 436 | (format t "All tests done!~%")
 | 
|---|
| [345] | 437 | 
 | 
|---|
 | 438 | 
 | 
|---|