;;; -*- Mode: Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; 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. ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defpackage "TERM" (:use :cl :monom :ring) (:export "TERM") (:documentation "This package implements class TERM. A term is a product of a scalar and powers of some variables, such as 5*X^2*Y^3. The part of the term without the coefficient is a monomial X^2*Y^3, which is represented by class MONOM, provided by the :MONOM package. In this implementation, a TERM specializes MONOL. Also, a monomial can be considered a TERM whose coefficient is the unit element (1) of the underlying ring. The generic method CHANGE-CLASS can be used to convert between a MONOM and a TERM, observing this convention.")) (in-package :term) (proclaim '(optimize (speed 3) (space 0) (safety 0) (debug 0))) ;; NOTE: Since term does not have slots of its own, ;; INITIALIZE-INSTANCE is not called by MAKE-INSTANCE. (defclass term (monom scalar) () (:documentation "Implements a term, i.e. a product of a scalar and powers of some variables, such as 5*X^2*Y^3.")) (defmethod print-object ((self term) stream) (print-unreadable-object (self stream :type t :identity t) (with-accessors ((exponents monom-exponents) (coeff scalar-coeff)) self (format stream "EXPONENTS=~A COEFF=~A" exponents coeff)))) (defmethod r-equalp ((term1 term) (term2 term)) (when (r-equalp (scalar-coeff term1) (scalar-coeff term2)) (call-next-method))) (defmethod update-instance-for-different-class :after ((old monom) (new scalar) &key) (setf (scalar-coeff new) 1)) (defmethod multiply-by :before ((self term) (other term)) "Destructively multiply terms SELF and OTHER and store the result into SELF. It returns SELF." (setf (scalar-coeff self) (multiply-by (scalar-coeff self) (scalar-coeff other)))) (defmethod left-tensor-product-by ((self term) (other term)) (setf (scalar-coeff self) (multiply-by (scalar-coeff self) (scalar-coeff other))) (call-next-method)) (defmethod right-tensor-product-by ((self term) (other term)) (setf (scalar-coeff self) (multiply-by (scalar-coeff self) (scalar-coeff other))) (call-next-method)) (defmethod left-tensor-product-by ((self term) (other monom)) (call-next-method)) (defmethod right-tensor-product-by ((self term) (other monom)) (call-next-method)) (defmethod divide-by ((self term) (other term)) "Destructively divide term SELF by OTHER and store the result into SELF. It returns SELF." (setf (scalar-coeff self) (divide-by (scalar-coeff self) (scalar-coeff other))) (call-next-method)) (defmethod unary-minus ((self term)) (setf (scalar-coeff self) (unary-minus (scalar-coeff self))) self) (defmethod r* ((term1 term) (term2 term)) "Non-destructively multiply TERM1 by TERM2." (multiply-by (copy-instance term1) (copy-instance term2))) (defmethod r* ((term1 number) (term2 monom)) "Non-destructively multiply TERM1 by TERM2." (r* term1 (change-class (copy-instance term2) 'term))) (defmethod r* ((term1 number) (term2 term)) "Non-destructively multiply TERM1 by TERM2." (setf (scalar-coeff term2) (r* term1 (scalar-coeff term2))) term2) (defmethod r-zerop ((self term)) (r-zerop (scalar-coeff self))) #| (defun term->cons (term) "A human-readable representation of a term as a cons (MONOM . COEFF)." (declare (type term term)) (cons (monom->list (term-monom term)) (scalar-coeff term))) |#