Menu

#2937 dotscrules and antisymmetric

closed
None
5
2015-04-24
2015-04-15
Leo Butler
No

Declaring . to be antisymmetric and setting dotscrules=true gives an erroneous simplification:

(%i1) (declare(a,scalar), declare(".",antisymmetric))$

(%i2) b . a;
(%o2)                               - a . b

Which is correct.

(%i3) b . a, dotscrules=true;
(%o3)                                - a b

Which is incorrect.

The problem is that antisym does not respect dotscrules.

Here is a patch that fixes the problem: antisym first checks if the dotscrules is true and if the expression should be simplified by simpnct, before doing its normal business.

The patch also removes antisym-sign as a special variable.

diff --git a/src/asum.lisp b/src/asum.lisp                                                                                                                                                                          
index c1d5836..158b6f7 100644                                                                                                                                                                                       
--- a/src/asum.lisp                                                                                                                                                                                                 
+++ b/src/asum.lisp                                                                                                                                                                                                 
@@ -993,26 +993,29 @@ summation when necessary."
 (setq opers (cons '$antisymmetric opers)                                                                                                                                                                           
       *opers-list (cons '($antisymmetric . antisym) *opers-list))                                                                                                                                                  

-(declare-top (special antisym-sign))                                                                                                                                                                               
-                                                                                                                                                                                                                   
 (defmfun antisym (e z)                                                                                                                                                                                             
-  (let ((l (mapcar #'(lambda (q) (simpcheck q z)) (cdr e))))                                                                                                                                                       
-    (let (antisym-sign) (if (or (not (eq (caar e) 'mnctimes)) (freel l 'mnctimes))                                                                                                                                 
-                   (setq l (bbsort1 l)))                                                                                                                                                                           
+  (when (and $dotscrules (mnctimesp e))                                                                                                                                                                            
+    (setq e (simpnct e 1 nil)))                                                                                                                                                                                    
+  (let ((antisym-sign nil)                                                                                                                                                                                         
+       (l (mapcar #'(lambda (q) (simpcheck q z)) (cdr e))))                                                                                                                                                        
+    (when (or (not (eq (caar e) 'mnctimes)) (freel l 'mnctimes))                                                                                                                                                   
+      (multiple-value-setq (l antisym-sign) (bbsort1 l)))                                                                                                                                                          
     (cond ((equal l 0) 0)                                                                                                                                                                                          
-              ((prog1 (null antisym-sign) (setq e (oper-apply (cons (car e) l) t)))                                                                                                                                
+         ((prog1                                                                                                                                                                                                   
+              (null antisym-sign)                                                                                                                                                                                  
+            (setq e (oper-apply (cons (car e) l) t)))                                                                                                                                                              
           e)                                                                                                                                                                                                       
-              (t (neg e))))))                                                                                                                                                                                      
+         (t (neg e)))))                                                                                                                                                                                            

 (defun bbsort1 (l)                                                                                                                                                                                                 
-  (prog (sl sl1)                                                                                                                                                                                                   
-     (if (or (null l) (null (cdr l))) (return l))                                                                                                                                                                  
-     (setq antisym-sign nil sl (list nil (car l)))                                                                                                                                                                 
+  (prog (sl sl1 antisym-sign)                                                                                                                                                                                      
+     (if (or (null l) (null (cdr l))) (return (values l antisym-sign))                                                                                                                                             
+        (setq sl (list nil (car l))))                                                                                                                                                                              
      loop (setq l (cdr l))                                                                                                                                                                                         
-     (if (null l) (return (nreverse (cdr sl))))                                                                                                                                                                    
+     (if (null l) (return (values (nreverse (cdr sl)) antisym-sign)))                                                                                                                                              
      (setq sl1 sl)                                                                                                                                                                                                 
      loop1(cond ((null (cdr sl1)) (rplacd sl1 (cons (car l) nil)))                                                                                                                                                 
-               ((alike1 (car l) (cadr sl1)) (return 0))                                                                                                                                                            
+               ((alike1 (car l) (cadr sl1)) (return (values 0 nil)))                                                                                                                                               
                ((great (car l) (cadr sl1)) (rplacd sl1 (cons (car l) (cdr sl1))))                                                                                                                                  
                (t (setq antisym-sign (not antisym-sign) sl1 (cdr sl1)) (go loop1)))                                                                                                                                
      (go loop)))                                                                                                                
diff --git a/src/mdot.lisp b/src/mdot.lisp                                                                                                                                                                          
index 1c3b1b8..cc6a435 100644                                                                                                                                                                                       
--- a/src/mdot.lisp                                                                                                                                                                                                 
+++ b/src/mdot.lisp                                                                                                                                                                                                 
@@ -86,7 +86,6 @@ is no need to rely on the setting of this switch.")
 ;; Specials defined elsewhere.                                                                                                                                                                                     

 (declare-top (special $expop $expon    ; Controls behavior of EXPAND                                                                                                                                               
-                     antisym-sign      ; track reversals when reordering noncommutative products                                                                                                                   
                      errorsw))                                                                                                                                                                                     

 ;; The operators "." and "^^" distribute over equations.                                                                                                                                                           
@@ -382,12 +381,11 @@ is no need to rely on the setting of this switch.")
       (rplacd (last inner-product) (ncons (car rest))))))                                                                                                                                                          

 (defun simpnct-antisym-check (l check)                                                                                                                                                                             
-  (let (antisym-sign)                                                                                                                                                                                              
   (cond ((and (get 'mnctimes '$antisymmetric) (cddr l))                                                                                                                                                            
-          (setq l (bbsort1 l))                                                                                                                                                                                     
+        (multiple-value-bind (l antisym-sign) (bbsort1 l)                                                                                                                                                          
           (cond ((equal l 0) 0)                                                                                                                                                                                    
                 ((prog1 (null antisym-sign)                                                                                                                                                                        
                    (setq l (eqtest (cons '(mnctimes) l) check)))                                                                                                                                                   
                  l)                                                                                                                                                                                                
-                (t (neg l))))                                                                                                                                                                                      
-         (t (eqtest (cons '(mnctimes) l) check)))))                                                                                                                                                                
+                (t (neg l)))))                                                                                                                                                                                     
+       (t (eqtest (cons '(mnctimes) l) check))))                                             

The testsuite runs without any unexpected error and we get the correct simplification.

~~~~~
Maxima branch_5_36_base_14_g7b066a8 http://maxima.sourceforge.net
using Lisp SBCL 1.2.4.debian
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) load("src/mdot.lisp");
(%o1) src/mdot.lisp
(%i2) load("src/asum.lisp");
(%o2) src/asum.lisp
(%i3) (declare(a,scalar), declare(".",antisymmetric))$

(%i4) b . a;
(%o4) - a . b
(%i5) b . a, dotscrules=true;
(%o5) a b
~~~~~~

Discussion

  • Leo Butler

    Leo Butler - 2015-04-24
    • status: open --> closed
     
  • Leo Butler

    Leo Butler - 2015-04-24

    This is fixed in commit 20b4b5e. There are 2 extra corner cases handled in that commit that are not in the patch above: 1. when simpnct returns a mapatom (invalid input to antisym), return that; 2. prevent simpnct from returning a term involving ^^ by binding $dotexptsimp to nil.

     

Log in to post a comment.

MongoDB Logo MongoDB