;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Copyright (C) 1999, 2002, 2009, 2015 Marek Rychlik ;;; ;;; This program is free software; you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 2 of the License, or ;;; (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software ;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (in-package :ngrobner) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Global switches ;; ;; Can be used in Maxima just fine, as they observe the ;; Maxima naming convention, i.e. all names visible at the ;; Maxima toplevel begin with a '$'. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar $poly_monomial_order '$lex "This switch controls which monomial order is used in polynomial and Grobner basis calculations. If not set, LEX will be used") (defvar $poly_coefficient_ring '$expression_ring "This switch indicates the coefficient ring of the polynomials that will be used in grobner calculations. If not set, Maxima's general expression ring will be used. This variable may be set to RING_OF_INTEGERS if desired.") (defvar $poly_primary_elimination_order nil "Name of the default order for eliminated variables in elimination-based functions. If not set, LEX will be used.") (defvar $poly_secondary_elimination_order nil "Name of the default order for kept variables in elimination-based functions. If not set, LEX will be used.") (defvar $poly_elimination_order nil "Name of the default elimination order used in elimination calculations. If set, it overrides the settings in variables POLY_PRIMARY_ELIMINATION_ORDER and SECONDARY_ELIMINATION_ORDER. The user must ensure that this is a true elimination order valid for the number of eliminated variables.") (defvar $poly_return_term_list nil "If set to T, all functions in this package will return each polynomial as a list of terms in the current monomial order rather than a Maxima general expression.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; These are provided mostly for debugging purposes To enable ;; verification of grobner bases with BUCHBERGER-CRITERION, do ;; (pushnew :grobner-check *features*) and compile/load this file. ;; With this feature, the calculations will slow down CONSIDERABLY. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun grobner-test (ring g f) "Test whether G is a Grobner basis and F is contained in G. Return T upon success and NIL otherwise." (debug-cgb "~&GROBNER CHECK: ") (let (($poly_grobner_debug nil) (stat1 (buchberger-criterion ring g)) (stat2 (every #'poly-zerop (makelist (normal-form ring (copy-tree (elt f i)) g nil) (i 0 (1- (length f))))))) (unless stat1 (error "~&Buchberger criterion failed.")) (unless stat2 (error "~&Original polys not in ideal spanned by Grobner."))) (debug-cgb "~&GROBNER CHECK END") t) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Conversion from internal to infix form ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun coerce-to-infix (poly-type object vars) "Write a polynomial, polynomial list, termlist term in infix form, using variables VARS. Can be used to display an internal form polynomial more readably." (case poly-type (:termlist `(+ ,@(mapcar #'(lambda (term) (coerce-to-infix :term term vars)) object))) (:polynomial (coerce-to-infix :termlist (poly-termlist object) vars)) (:poly-list `([ ,@(mapcar #'(lambda (p) (coerce-to-infix :polynomial p vars)) object))) (:term `(* ,(term-coeff object) ,@(mapcar #'(lambda (var power) `(expt ,var ,power)) vars (coerce (term-monom object) 'list)))) (otherwise object))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Order utilities ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun find-order (order) "This function returns the order function bases on its name." (cond ((null order) nil) ((symbolp order) (case order ((lex :lex $lex) #'lex>) ((grlex :grlex $grlex) #'grlex>) ((grevlex :grevlex $grevlex) #'grevlex>) ((invlex :invlex $invlex) #'invlex>) ((elimination-order-1 :elimination-order-1 elimination_order_1) #'elimination-order-1) (otherwise (warn "~%Warning: Order ~A not found. Using default.~%" order)))) (t (warn "~%Order specification ~A is not recognized. Using default.~%" order) nil))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Ring utilities ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun find-ring (ring) "This function returns the ring structure bases on input symbol." (cond ((null ring) nil) ((symbolp ring) (case ring ((expression-ring :expression-ring $expression_ring) *expression-ring*) ((ring-of-integers :ring-of-integers $ring_of_integers) *ring-of-integers*) (otherwise (warn "~%Warning: Ring ~A not found. Using default.~%" ring)))) (t (warn "~%Ring specification ~A is not recognized. Using default.~%" ring) nil)))