;;;This is the public version of the code for the proofs in "Affine partitions and Affine Grassmannians" by Billey and Mitchell. ;;; The proofs in that article are verified using the following commands: ;;;(gather-affine-data 8 40) = lists palindromics for B-G. Can be modified to include type A but many more palindromics exits ;;;(grind-affine-partition-gf 'affine-g 2 20) ;;; these give the generating functions for affine partitions in each type. ;;;(grind-affine-partition-gf 'affine-f 4 20) ;;;(grind-affine-partition-gf 'affine-e 6 40) ;;;(grind-affine-partition-gf 'affine-e 7 40) ;;;(grind-affine-partition-gf 'affine-e 8 40) (in-package :user) (defun start-up () (cfl "affine.partitions.lisp")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; from coxeter.lisp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; code to generate all or part of a Coxeter group ;;;;just from the Coxeter matrix. Affine Weyl groups also encoded. ;;; coroot lattice notation and eriksson all 1's vector notation included. (defun make-coxeter-group (cox-matrix thresh &optional (type 'new-type)) ;;; cmatrix is a Coxeter matrix and thresh is a length threshold (setf *cox-matrix* cox-matrix) (setf *n* (array-dimension *cox-matrix* 0)) ;;; rank of the Coxeter group (setf *type* (cons type *n*)) (setf *thresh* thresh) (setf *cox-group-hash* (make-hash-table :test 'equal)) (setf *identity-element* (loop for i from 1 to *n* collect 1)) (push *identity-element* (gethash 0 *cox-group-hash*)) (loop for i from 1 to thresh do (cox-group-helper i))) (defun make-coxeter-group-quotient (cox-matrix thresh parab &optional (type 'new-type)) ;;; cmatrix is a Coxeter matrix and thresh is a length threshold (make-coxeter-group cox-matrix thresh type) (setf *type* (list (cons type *n*) 'mod parab)) o (setf *parabolic* parab) (setf *gens* (if (member type (list 'affine-b 'affine-d :test 'equal)) '(0 1) '(0))) (setf *one-elem-index* '(0)) (setf *cox-quotient-hash* (make-hash-table :test 'equal)) (push *identity-element* (gethash 0 *cox-quotient-hash*)) (loop for i from 1 to thresh do (format t "~a." i) (cox-quotient-helper i parab))) (defun make-affine-weyl-group (type n thresh) ;;; cmatrix is a Coxeter matrix and thresh is a length threshold (setf *type* (cons type n)) (setf *cox-matrix* (make-coxeter-matrix type (1+ n))) (setf *thresh* thresh) (setf *cox-1-chain* (append (loop for k from 1 to n collect k) (loop for k downfrom (1- n) to 1 collect k))) (setf *cox-0-chain* (append '(0) (loop for k from 2 to n collect k) (loop for k downfrom (1- n) to 2 collect k) '(0))) (setf *n* (array-dimension *cox-matrix* 0)) ;;; rank of the Coxeter group (setf *cox-group-hash* (make-hash-table :test 'equal)) (setf *coroot-identity-element* (cons 1 (loop for i from 1 to n collect 0))) (setf *identity-element* (loop for i from 1 to *n* collect 1)) (push *identity-element* (gethash 0 *cox-group-hash*)) (loop for i from 1 to thresh do (format t " ~a" i) (cox-group-helper i))) (defun make-affine-quotient (type n thresh &optional (parabolic nil)) (let ((parab (if parabolic parabolic (loop for i from 1 to n collect i)))) ;;; cmatrix is a Coxeter matrix and thresh is a length threshold (make-affine-weyl-group type n 0) (setf *type* (list (cons type n) 'mod parab)) (setf *thresh* thresh) (setf *parabolic* parab) (setf *gens* (if (member type '(affine-b affine-d) :test 'equal) '(1 0) '(0))) (setf *one-elem-index* '(0)) (setf *cox-quotient-hash* (make-hash-table :test 'equal)) (push *identity-element* (gethash 0 *cox-quotient-hash*)) (loop for i from 1 to thresh do (format t "~a." i) (cox-quotient-helper i parab)))) (defun make-standard-affine-quotient (type n thresh &optional (parabolic nil)) ;;;; was this written before and lost? (let ((parab (if parabolic parabolic (loop for i from 1 to n collect i)))) ;;; cmatrix is a Coxeter matrix and thresh is a length threshold (make-affine-weyl-group type n 0) (setf *type* (list (cons type n) 'mod parab)) (setf *thresh* thresh) (setf *parabolic* (loop for i from 1 to n collect i)) (setf *gens* (if (member type '(affine-b affine-d) :test 'equal) '(1 0) '(0))) (setf *one-elem-index* '(0)) (setf *cox-quotient-hash* (make-hash-table :test 'equal)) (push *identity-element* (gethash 0 *cox-quotient-hash*)) (loop for i from 1 to thresh do (format t "~a." i) (cox-quotient-helper i parab)))) (defun cox-quotient-helper (index parab) (let ((new-elem nil)) (loop for elem in (gethash (1- index) *cox-quotient-hash*) do (loop for gen from 0 below *n* do (setf new-elem (fire-node-left gen elem)) (when (and (min-length-coset-rep-p new-elem parab) (= (cox-length new-elem) index) (not (member new-elem (gethash index *cox-quotient-hash*) :test 'equal))) (push new-elem (gethash index *cox-quotient-hash*))))) (when (= 1 (length (gethash index *cox-quotient-hash*))) (push index *one-elem-index*)))) (defun make-wely-group (type n thresh &optional(rows nil)) ;;; cmatrix is a Coxeter matrix and thresh is a length threshold (setf *type* (cons type n)) (setf *cox-matrix* (make-coxeter-matrix type n rows)) (setf *thresh* thresh) (setf *n* n) (setf *cox-group-hash* (make-hash-table :test 'equal)) (setf *identity-element* (loop for i from 1 to *n* collect 1)) (push *identity-element* (gethash 0 *cox-group-hash*)) (loop for i from 1 to thresh do (cox-group-helper i))) (defun cox-group-helper (index) (let ((new-elem nil)) (loop for elem in (gethash (1- index) *cox-group-hash*) do (loop for val in elem for gen from 0 below *n* when (< 0 val) do (setf new-elem (fire-node gen elem)) (when (not (member new-elem (gethash index *cox-group-hash*) :test 'equal)) (push new-elem (gethash index *cox-group-hash*))))))) (defun fire-node (gen elem) (let ((node-weight (nth gen elem))) (loop for val in elem for j from 0 collect (+ val (* (aref *cox-matrix* gen j) node-weight))))) (defun fire-node-left (gen elem) (cox-build-elem (cons gen (cox-find-reduced elem)))) (defun make-coxeter-matrix (type n &optional (rows nil)) (let ((mat nil)) (cond (rows (setf mat (make-array (list n n) :initial-contents rows))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((equal type 'a) (setf mat (make-array (list n n) )) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((and (equal type 'affine-a) (= n 2)) (setf mat (make-array (list n n) )) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 0 i) (= (1- n) j)) 4) ((and (= (1- n) i) (= 0 j)) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((equal type 'affine-a) (setf mat (make-array (list n n) )) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((= (abs (- i j)) 1) 1) ((and (= 0 i) (= (1- n) j)) 1) ((and (= (1- n) i) (= 0 j)) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;From BB, chose edge weights k_{i,j) k_(j,i) = 4 cos^2(pi/m(s_i,s_j)) ;;for m=3 use 1,1; for m=4 use 2,1; for m=6 use 3,1; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((equal type 'b) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= (- n 2) i) (= (- n 1) j)) 2) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((and (= n 3) (or (equal type 'affine-b) (equal type 'affine-c) )) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 0 i) (= 1 j)) 2) ((and (= (- n 2) i) (= (- n 1) j)) 2) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((equal type 'affine-b) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 0 i) (= 1 j)) 0) ((and (= 0 j) (= 1 i)) 0) ((and (= 0 i) (= 2 j)) 1) ((and (= 0 j) (= 2 i)) 1) ((and (= (- n 2) j) (= (- n 1) i)) 2) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((equal type 'affine-c) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 0 i) (= 1 j)) 2) ((and (= (- n 2) j) (= (- n 1) i)) 2) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((equal type 'd) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 0 i) (= 1 j)) 0) ((and (= 0 j) (= 1 i)) 0) ((and (= 0 i) (= 2 j)) 1) ((and (= 0 j) (= 2 i)) 1) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((equal type 'affine-d) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 0 i) (= 1 j)) 0) ((and (= 0 j) (= 1 i)) 0) ((and (= 0 i) (= 2 j)) 1) ((and (= 0 j) (= 2 i)) 1) ((and (= (- n 2) i) (= (- n 1) j)) 0) ((and (= (- n 2) j) (= (- n 1) i)) 0) ((and (= (- n 3) i) (= (- n 1) j)) 1) ((and (= (- n 3) j) (= (- n 1) i)) 1) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((and (equal type 'affine-e) ;;; \tilde{E}_6 (= n 7)) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 1 i) (= 2 j)) 0) ;; 2-3-4-5-6 ((and (= 1 j) (= 2 i)) 0) ;; | ((and (= 1 i) (= 4 j)) 1) ;; 1 ((and (= 1 j) (= 4 i)) 1) ;; | ((= (abs (- i j)) 1) 1) ;; 0 (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((and (equal type 'affine-e) ;;; \tilde{E}_7 (= n 8)) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 0 i) (= 1 j)) 0) ;; 0-2-3-4-5-6-7 ((and (= 0 j) (= 1 i)) 0) ;; | ((and (= 0 i) (= 2 j)) 1) ;; 1 ((and (= 0 j) (= 2 i)) 1) ((and (= 1 i) (= 2 j)) 0) ((and (= 1 j) (= 2 i)) 0) ((and (= 1 i) (= 4 j)) 1) ((and (= 1 j) (= 4 i)) 1) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((and (equal type 'affine-e) ;;; \tilde{E}_8 (= n 9)) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 0 i) (= 1 j)) 0) ;; 2-3-4-5-6-7-8-0 ((and (= 0 j) (= 1 i)) 0) ;; | ((and (= 0 i) (= 8 j)) 1) ;; 1 ((and (= 0 j) (= 8 i)) 1) ((and (= 1 i) (= 2 j)) 0) ((and (= 1 j) (= 2 i)) 0) ((and (= 1 i) (= 4 j)) 1) ((and (= 1 j) (= 4 i)) 1) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((and (equal type 'new-affine-e) ;;; \tilde{E}_6 (= n 7)) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 5 i) (= 2 j)) 1) ;; 4-3-2-5-6 ((and (= 5 j) (= 2 i)) 1) ;; | ((and (= 5 i) (= 4 j)) 0) ;; 1 ((and (= 5 j) (= 4 i)) 0) ;; | ((= (abs (- i j)) 1) 1) ;; 0 (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((and (equal type 'new-affine-e) ;;; \tilde{E}_7 (= n 8)) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 0 i) (= 1 j)) 1) ;; 0-1-2-3-5-6-7 ((and (= 0 j) (= 1 i)) 1) ;; | ((and (= 3 i) (= 5 j)) 1) ;; 4 ((and (= 3 j) (= 5 i)) 1) ((and (= 4 i) (= 5 j)) 0) ((and (= 4 j) (= 5 i)) 0) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((and (equal type 'new-affine-e) ;;; \tilde{E}_8 (= n 9)) (setf mat (make-array (list n n))) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 0 i) (= 1 j)) 0) ;; 8-7-5-4-3-2-1-0 ((and (= 0 j) (= 1 i)) 0) ;; | ((and (= 7 i) (= 5 j)) 1) ;; 6 ((and (= 7 j) (= 5 i)) 1) ((and (= 6 i) (= 7 j)) 0) ((and (= 6 j) (= 7 i)) 0) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((equal type 'affine-f) (setf mat (make-array (list n n) )) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ;((and (= 2 i) (= 3 j)) 2) ((and (= 3 i) (= 2 j)) 2) ((= (abs (- i j)) 1) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((equal type 'affine-g) (setf mat (make-array (list n n) )) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 2 i) (= 1 j)) 3) ((and (= 2 j) (= 1 i)) 1) ((and (= 0 j) (= 2 i)) 1) ((and (= 0 i) (= 2 j)) 1) (t 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ((equal type 'new-affine-g) (setf mat (make-array (list n n) )) (loop for i from 0 below n do (loop for j from 0 below n do (setf (aref mat i j ) (cond ((= i j) -2) ((and (= 2 j) (= 1 i)) 3) ;;; >3> ((and (= 2 i) (= 1 j)) 1) ;;; 0-1--- 2 ((and (= 0 j) (= 2 i)) 0) ((and (= 0 i) (= 1 j)) 1) ((and (= 0 j) (= 1 i)) 1) (t 0)))))) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mat)) (defun min-length-coset-rep-hash (parabolic-subgroup-gens) (let ((new-hash (make-hash-table :test 'equal))) (maphash #'(lambda (key val) (setf (gethash key new-hash) (loop for elem in val when (min-length-coset-rep-p elem parabolic-subgroup-gens) collect elem))) *cox-group-hash*) new-hash)) (defun min-length-coset-rep-p (elem parabolic-subgroup-gens) (catch 'foo (loop for j in parabolic-subgroup-gens for val = (nth j elem) when (> 0 val) do (throw 'foo nil)) (throw 'foo t))) (defun cox-find-reduced (elem &optional (priority '(0 1))) (if (member (caar *type*) (list 'affine-d 'affine-b) :test 'equal) (reverse (cox-find-reduced-helper-b elem priority *identity-element*)) (reverse (cox-find-reduced-helper elem *identity-element*)))) (defun cox-find-reduced-helper (elem identity) (let ((last-descent nil)) (if (equal elem identity) nil (progn (setf last-descent (loop for e in (reverse elem) for j downfrom (1- (length elem) ) until (> 0 e) finally (return j))) (cons last-descent (cox-find-reduced-helper (fire-node last-descent elem) identity)) )))) (defun cox-find-reduced-helper-b (elem priority identity) (let ((descents nil)) (if (equal elem identity) nil (progn (setf descents (loop for e in (reverse elem) for j downfrom (1- (length elem) ) when (> 0 e) collect j)) (if (same-lists-p descents '(1 0)) (cons (car priority) (cox-find-reduced-helper-b (fire-node (car priority) elem) (reverse priority) identity)) (cons (car descents) (cox-find-reduced-helper-b (fire-node (car descents) elem) priority identity))))))) (defun cox-length (elem) (length (cox-find-reduced elem))) (defun cox-identity-p (elem) (equal *identity-element* elem)) ;;;; steve's coroot lattice notation (defun cox-build-coroot (word) ;; takes in a red word for a min length coset rep, reverses it, and builds coroot (let ((elem (cons 1 (loop for i from 1 below *n* collect 0)))) (loop for gen in (reverse word) do (setf elem (fire-node gen elem))) elem)) (defun cox-elem-to-coroot (elem) (cox-build-coroot (cox-find-reduced elem))) (defun coroot-to-cox-elem (elem) (cox-build-elem (coroot-find-reduced elem))) (defun coroot-find-reduced (elem &optional (priority '(0 1))) ;; doesn't give same red word as cox-red word (if (member (caar *type*) (list 'affine-d 'affine-b) :test 'equal) (cox-find-reduced-helper-b elem priority *coroot-identity-element*) (cox-find-reduced-helper elem *coroot-identity-element*))) (defun coroot-to-partition (elem) (cox-partition *gens* (cox-find-reduced (coroot-to-cox-elem elem)))) (defun cox-dominant-vector-p (coroot) (catch 'foo (loop for i in *parabolic* when (> 0 (nth i coroot)) do (throw 'foo nil)) (throw 'foo t))) (defun cox-antidominant-vector-p (coroot) (catch 'foo (loop for i in *parabolic* when (< 0 (nth i coroot)) do (throw 'foo nil)) (throw 'foo t))) (defun cox-dominant-p (elem) (cox-dominant-vector-p (cox-build-elem (reverse (cox-find-reduced elem))))) (defun cox-antidominant-p (elem) (cox-antidominant-vector-p (cox-build-elem (reverse (cox-find-reduced elem))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; Bruhat order (defun create-bruhat-hash () (let ((new-hash (make-hash-table :test 'equal))) (maphash #'(lambda (key val) (loop for elem in val do (setf (gethash elem new-hash) (cox-covered-elems elem)))) *cox-group-hash*) (setf *bruhat-hash* new-hash) *bruhat-hash*)) ;(defun-create-weak-covering-hash () ; (let ((graph (make-hash-table :test #'equal)) ; (bruhat-hash *bruhat-hash*)) ; (maphash #'(lambda (key val) ; (loop for y in val do ; (loop for x in ;;;; check here (gethash (1- key) bruhat-hash) ; when (cox-left-weak-order-p x y) ; do (push x (gethash y graph))))) ; bruhat-hash) ; (push nil (gethash (first (gethash 0 bruhat-hash)) graph)) ; graph)) ;(defun cox-left-weak-order-p (x y) ; (= 1 (cox-length (cox-build-elem (reverse ( y)))) (defun create-quotient-bruhat-hash () (let ((new-hash (make-hash-table :test 'equal))) (maphash #'(lambda (key val) (loop for elem in val do (setf (gethash elem new-hash) (cox-covered-elems elem (nth 2 *type*))))) *cox-quotient-hash*) (setf *quotient-bruhat-hash* new-hash) *quotient-bruhat-hash*)) ;CL-USER(24): (make-coxeter-group 'affine-a 4 10) ;NIL ;CL-USER(25): (graphviz *quotient-bruhat-hash* "affine.a4.Quot.dot") (defun cox-build-elem (word &optional (start-elem *identity-element*)) (let ((elem (copy-list start-elem))) (loop for gen in word do (setf elem (fire-node gen elem))) elem)) (defun cox-reduced-build-elem (word &optional (start-elem *identity-element*)) (let ((elem (copy-list start-elem))) (catch 'foo (loop for gen in word for val = (nth gen elem) do (when (> 0 val) (setf elem nil) (throw 'foo nil)) (setf elem (fire-node gen elem)) ) (throw 'foo 't)) elem)) (defun cox-covered-elems (elem &optional (parab nil)) (when (not (cox-identity-p elem)) (let ((redword (cox-find-reduced elem)) (init-elem *identity-element*) (new-elem nil) (covered-elems nil)) (push (cox-build-elem (cdr redword)) covered-elems) (loop for gen in redword for j from 2 to (length redword) do (setf init-elem (fire-node gen init-elem)) (setf new-elem (cox-build-elem (nthcdr j redword) init-elem)) (when (and (min-length-coset-rep-p new-elem parab) (= (1- (length redword)) (cox-length new-elem))) (push new-elem covered-elems))) covered-elems))) ;;start here define a function to use graphviz to see the left weak order related to segment relations. (defun cox-covering-elems (elem poset) (let ((result nil)) (maphash #'(lambda (key val) (when (member elem val :test 'equal) (push key result))) poset) result)) (defun cox-poincare (elem bruhat-hash group-hash &optional (palindrom-steps 0)) ;; ;*quotient-bruhat-hash* *cox-quotient-hash* ;;(1- *one-elem-index*)) (reverse (cons 1 (cox-poincare-helper (1- (cox-length elem)) (gethash elem bruhat-hash) bruhat-hash group-hash palindrom-steps)))) (defun cox-poincare-helper (index elem-list bruhat-hash group-hash &optional (palindrom-steps 0)) (when (and elem-list (or (> 1 palindrom-steps) (= 1 (length elem-list)))) (if (= (length (gethash index group-hash)) (length elem-list)) (loop for i downfrom index to 0 collect (length (gethash i group-hash))) (let ((covered-elems nil)) (loop for elem in elem-list do (loop for covered-elem in (gethash elem bruhat-hash) when (not (member covered-elem covered-elems :test 'equal)) do (push covered-elem covered-elems))) (cons (length elem-list) (cox-poincare-helper (1- index) covered-elems bruhat-hash group-hash (1- palindrom-steps))))))) (defun cox-palindromic-p (elem bruhat-hash group-hash) (let ((poincare (cox-poincare elem bruhat-hash group-hash (1- (length *one-elem-index*))))) (and (= (length poincare) (1+ (cox-length elem))) ;;; this is a shortcut for when the break point is up near the max so we don't build the whole poincare poly (symmetric-list-p poincare)))) ;; in fact we only need to test symmetric when it actually is symmetric by the shortcut above (defun poincare-symmetry-break-point (elem bruhat-hash group-hash) (let ((poincare (cox-poincare elem bruhat-hash group-hash (1- (length *one-elem-index*))))) (when (and (not (= (length poincare) (1+ (cox-length elem)))) (= (length poincare) (1- (length *one-elem-index*)))) (push elem *long-chains*)) (if (= (length poincare) (1+ (cox-length elem))) (symmetry-break-point poincare) (length poincare)))) (setf *palindromic-hash* (make-hash-table :test 'equal)) (defun cox-find-palindromics (bruhat-hash group-hash gens &optional (verbose t)) (let ((palindromics nil) (poincare-break 1)) (maphash #'(lambda (key val) (if (cox-palindromic-p key bruhat-hash group-hash) (push key palindromics) (setf poincare-break (max poincare-break (poincare-symmetry-break-point key bruhat-hash group-hash))) )) bruhat-hash) (setf *poincare-break-point* poincare-break) (setf palindromics (sort (copy-list palindromics) 'cox-length-order) ) (when verbose (format t "~%~%IN TYPE: ~a ~a, thresh= ~a number of palindromics = ~a " *type* *n* *thresh* (length palindromics)) (format t "~%Max-Poincare-break-point:~a" poincare-break) (format t "~%First-break-point-at-length:~a" (length *one-elem-index*)) (loop for elem in palindromics do (format t "~%~a: partition: ~a length: ~a ~% redword: ~a~% poincare = ~a " (cox-elem-to-coroot elem) (loop for seg in (find-all-segments gens (cox-find-reduced elem)) collect (length seg)) (cox-length elem) (cox-find-reduced elem ) (cox-poincare elem bruhat-hash group-hash) ))) (setf (gethash *type* *palindromic-hash*) palindromics) palindromics)) (defun test-standard-quotient-palindromics (type n thresh ) (setf *long-chains* nil) (setf *gens* (if (member type (list 'affine-b 'affine-d :test 'equal)) '(1 0) '(0))) (make-affine-quotient type n thresh (loop for i from 1 to n collect i) ) (create-quotient-bruhat-hash) ;(format t "bruhat-poset-complete") (mapcar 'cox-elem-to-coroot (cox-find-palindromics *quotient-bruhat-hash* *cox-quotient-hash* *gens*))) (defun gather-affine-data (max-n thresh) (loop for type in '(affine-b affine-c affine-d) do (format t "~%~%**********************************************************************~% ******* Type ~a n=2 to ~a **************************************~% **********************************************************************~%" type max-n) (loop for n from 2 to max-n do (test-standard-quotient-palindromics type n thresh ))) (format t "~%~%**********************************************************************~% ******* Type E n=6 to 8 **************************************~% **********************************************************************~%" ) (loop for n from 6 to 8 do (test-standard-quotient-palindromics 'affine-e n thresh )) (format t "~%~%**********************************************************************~% ******* Type F n=4 **************************************~% **********************************************************************~%" ) (test-standard-quotient-palindromics 'affine-f 4 thresh ) (format t "~%~%**********************************************************************~% ******* Type G n=2 **************************************~% **********************************************************************~%" ) (test-standard-quotient-palindromics 'affine-g 2 thresh )) (defun cox-length-order (perm1 perm2) (< (cox-length perm1) (cox-length perm2 ))) (defun palindromic-sequence (type start stop) (loop for i from start to stop collect (length (car (gethash (list (cons type i) 'mod (loop for j from 1 to i collect j)) *palindromic-hash*))))) (defun cox-interval (bruhat-hash elem) (let ((hash (make-hash-table :test 'equal))) (rec-cox-interval bruhat-hash (list elem) hash) hash)) (defun restricted-cox-interval-in-coroots (elem i j) (let ((bruhat-hash (cox-interval *quotient-bruhat-hash* elem)) (hash (make-hash-table :test 'equal))) (maphash #'(lambda (key val) (when (and (< i (cox-length key)) (< (cox-length key) j)) (setf (gethash (cox-elem-to-coroot key) hash) (loop for v in val collect (cox-elem-to-coroot v))))) bruhat-hash) hash)) (defun rec-cox-interval (bruhat-hash elem-list hash) (when elem-list (let ((new-elems nil)) (loop for elem in elem-list do (setf (gethash elem hash) (gethash elem bruhat-hash)) (setf new-elems (append (gethash elem hash) new-elems))) (rec-cox-interval bruhat-hash (unique-elems new-elems) hash)))) (defun print-cox-poset (poset max-rank) (let ((ranks (make-array (list (1+ max-rank))))) (maphash #'(lambda (key val) (push key (aref ranks (cox-length key)))) poset) (loop for i downfrom max-rank to 0 do (print (aref ranks i))))) (defun cox-right-weak-interval (elem) ;;; for coxeter group (let ((hash (make-hash-table :test 'equal))) (rec-cox-right-weak-interval (list elem) hash) hash)) (defun rec-cox-right-weak-interval (elem-list hash) (when elem-list (let ((new-elems nil)) (loop for elem in elem-list for covers = (loop for i from 0 below *n* when (> 0 (nth i elem)) collect (fire-node i elem)) do (setf (gethash elem hash) covers) (setf new-elems (append new-elems covers))) (rec-cox-right-weak-interval (unique-elems new-elems) hash)))) (defun cox-left-weak-interval (coroot) ;;; for standard quotients (let ((hash (make-hash-table :test 'equal))) (rec-cox-left-weak-interval (list coroot) hash) hash)) (defun rec-cox-left-weak-interval (coroot-list hash) (when coroot-list (let ((new-coroots nil)) (loop for coroot in coroot-list for covers = (loop for i from 0 below *n* when (> 0 (nth i coroot)) collect (fire-node i coroot)) do (setf (gethash coroot hash) covers) (setf new-coroots (append new-coroots covers))) (rec-cox-left-weak-interval (unique-elems new-coroots) hash)))) ;(graphviz (cox-interval *quotient-bruhat-hash* '(-5 1 1 1 7)) "block.3.dot") ; dot -Tps block.5.dot -o block.5.ps ;;;;; strict partitions (defun make-strict-partitions (thresh ) (let ((new-elem nil)) (setf *strict-partitions* (make-hash-table :test 'equal)) (setf *strict-partitions-poset* (make-hash-table :test 'equal)) (setf (gethash 0 *strict-partitions*) (list '())) (setf (gethash 1 *strict-partitions*) (list '(1))) (setf (gethash '(1) *strict-partitions-poset*) (list '())) (loop for index from 2 to thresh do (loop for elem in (gethash (1- index) *strict-partitions*) do ;;;; add new part of size 1 if possible (when (< 1 (car elem)) (when-new-elem-add (cons 1 elem) elem *strict-partitions* *strict-partitions-poset* index)) ;;;; add 1 to last component if possible (setf new-elem (reverse elem)) (setf new-elem (reverse (cons (1+ (car new-elem)) (cdr new-elem)))) (when-new-elem-add new-elem elem *strict-partitions* *strict-partitions-poset* index) ;;; increment parts if possible (up to last part) (loop for e-i in elem for e-i+1 in (cdr elem) for i from 0 when (< e-i (1- e-i+1)) do (when-new-elem-add (append (first-n i elem) (cons (1+ (nth i elem)) (nthcdr (1+ i) elem))) elem *strict-partitions* *strict-partitions-poset* index)))))) (defun test-odd-parts (partition max-odd) (catch 'foo (loop for n in partition when (null(test-odd-part n max-odd)) do (throw 'foo nil)) (throw 'foo t))) (defun test-odd-part (n max-odd) (if (evenp n) (test-odd-part (/ n 2) max-odd) (<= n max-odd))) (defun when-new-elem-add (new-elem old-elem ranked-hash poset-hash index) (push old-elem (gethash new-elem poset-hash)) (when (not (member new-elem (gethash index ranked-hash) :test 'equal)) (push new-elem (gethash index ranked-hash)))) (defun make-strict-partitions-restricted (thresh k) ;;; grow all partitions (make-strict-partitions thresh) ;;; set up restricted partitions (setf *restricted-partitions* (make-hash-table :test 'equal)) (setf *restricted-partitions-poset* (make-hash-table :test 'equal)) (loop for i from 0 to thresh do (loop for elem in (gethash i *strict-partitions*) when (test-odd-parts elem k) do (push elem (gethash i *restricted-partitions*)) (setf (gethash elem *restricted-partitions-poset*) (intersect-lists (list (gethash elem *strict-partitions-poset*) (gethash (1- i) *restricted-partitions*))))))) (defun test-rank-gen-conjecture (thresh n) ;;; true by theorem of Bott ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (make-strict-partitions-restricted thresh (1- (* 2 n))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (make-affine-quotient 'affine-b n thresh (loop for i from 1 to n collect i) ) (if (equal (loop for i from 0 below n collect (length (gethash i *cox-quotient-hash*))) (loop for i from 0 below n collect (length (gethash i *restricted-partitions*)))) (format t "~%True: ~a~%" *type*) (format t "~%~%~%False!!: ~a~%~%" *type*)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (make-affine-quotient 'affine-c n thresh (loop for i from 1 to n collect i) ) (if (equal (loop for i from 0 below n collect (length (gethash i *cox-quotient-hash*))) (loop for i from 0 below n collect (length (gethash i *restricted-partitions*)))) (format t "~%True: ~a~%" *type*) (format t "~%~%False!!: ~a ~%" *type*))) (defun test-all-partitions-of-n-restricted (n ) (let ((results nil) (maxval (1- (* 2 (1- *n*)))) (tail-elem nil) (parab (loop for i from 1 below *n* collect i))) (flet ((helper (tail) (when (and (= n (apply '+ tail)) (> 2 (count-matches 1 tail)) (> 2 (count-matches 2 tail)) (> 2 (count-matches 3 tail))) (setf tail-elem (cox-build-elem (partition-word tail))) (when (and (= (apply `+ tail) (cox-length tail-elem)) (min-length-coset-rep-p tail-elem parab)) (push tail results))))) (all-partitions-tester n 0 maxval #'helper nil)) results)) (defun partition-word (part) (reverse (loop for i in part for j from 0 append (if (evenp j) (cox-chain 0 i) (cox-chain 1 i))))) (defun cox-chain (init-gen i) (if (= 1 init-gen) (first-n i *cox-1-chain*) (first-n i *cox-0-chain*))) (defun cox-initial-segment (gen word) (first-n (1+ (position-n word gen)) word)) ;(defun find-all-segments (gens word) ; (let ((piece nil) ; (segments nil)) ; (loop for w in word ; do (push w piece) ; (when (member w gens :test 'equal) ; (push (reverse piece) segments) ; (setf piece nil))) ; (reverse segments))) (defun find-all-segments (gens word) (let ((piece nil) (segments nil)) (loop for w in (reverse word) do (cond ((null piece) (push w piece)) ((not (member w gens :test 'equal)) (push w piece)) ((and (< 1 (length gens)) (= w (car (last piece)))) (push w piece)) (t (push piece segments) (setf piece nil) (push w piece)))) (cons piece segments))) (defun cox-elem-to-partition (elem) (loop for seg in (find-all-segments *gens* (cox-find-reduced elem)) collect (length seg))) (defun cox-elem-to-colored-partition (elem) (when (not (equal elem *identity-element*)) (loop for seg in (find-all-segments *gens* (cox-find-reduced elem)) collect (gethash seg *cox-segment-names*)))) (defun cpart-to-cox-elem (cpart) (cox-segments-to-elem (loop for part in cpart collect (cox-segment (cpart-size part) (cpart-color part))))) (defun cox-partition (gens word) (loop for segment in (find-all-segments gens word) collect (length segment))) (defun grind-cox-partitions (gens &optional (verbose t)) (let ((partitions nil) (segment-types nil)) (loop for i from 0 to *thresh* do (loop for elem in (gethash i *cox-quotient-hash*) for partition = (cox-partition gens (cox-find-reduced elem)) for segments = (find-all-segments gens (cox-find-reduced elem)) do (when (not (member partition partitions :test 'equal)) (push partition partitions) (when (not (increasing-p partition)) (print (list 'not-increasing partition)))) (loop for segment in segments do (when (not (member segment segment-types :test 'equal)) (push segment segment-types))) )) ;;; setup segments and cross ref names (setf *cox-segments* (make-array (list (1+ (find-supremum (mapcar #'length segment-types) '>))))) (loop for segment in segment-types do (push segment (aref *cox-segments* (length segment)))) (loop for i from 1 to (find-supremum (mapcar #'length segment-types) '>) do (setf (aref *cox-segments* i) (sort (aref *cox-segments* i) 'lex-order)) (when verbose (loop for segment in (aref *cox-segments* i) do (format t "~%~a len: ~a" segment (length segment)) ))) (set-segment-name-hash gens) ;;; setup partitions (setf *cox-partitions* (make-array (list (1+ (find-supremum (mapcar #'length partitions) '>))))) (loop for part in partitions do (push part (aref *cox-partitions* (length part)))) *cox-partitions*)) (defun weak-order-colored-parts () ;;; copy from weak order on segments (setf *colored-parts-order* (make-hash-table :test 'equal)) (let* ((longest-segment (car (aref *cox-segments* (1- (array-dimension *cox-segments* 0))))) (weak-order-interval (cox-left-weak-interval (cox-build-coroot longest-segment))) (coroot-names (make-hash-table :test 'equal))) (maphash #'(lambda (key val) (setf (gethash key coroot-names) (coroot-segment-to-colored-part key))) weak-order-interval) (maphash #'(lambda (key val) (cond ((null val) nil) ((equal key (cox-build-coroot '(0))) (setf (gethash (gethash key coroot-names) *colored-parts-order*) nil)) (t (setf (gethash (gethash key coroot-names) *colored-parts-order*) (loop for coroot in val collect (gethash coroot coroot-names)))))) weak-order-interval)) *colored-parts-order*) (defun coroot-segment-to-colored-part (coroot) (gethash (cox-find-reduced (coroot-to-cox-elem coroot)) *cox-segment-names*)) (defun determine-gen-segment-relations (&optional (end nil)) (loop for i from 1 below (array-dimension *cox-segments* 0) do (loop for seg in (aref *cox-segments* i) when (and end (member (car (last seg)) end :test '=)) do (format t "~%~%Segment: ~a j=~a ~%Relations: ~a " seg (length seg) (commutation-finder seg))))) (defun commutation-finder (word) (let ((commuting nil) (modified nil) (non-commuting nil)) (loop for i from 0 below *n* for v = (cox-build-elem (cons i word)) do (if (equal v (cox-build-elem (append word (list i)))) (push i commuting) (when (catch 'foo (loop for j from 0 below *n* for w = (cox-build-elem (append word (list j))) when (equal w v) do (push (cons i j) modified) (throw 'foo nil)) (throw 'foo t)) (push i non-commuting)))) (list commuting modified non-commuting))) (defun set-segment-name-hash (gens) (setf *cox-segment-names* (make-hash-table :test 'equal)) (setf *cox-segments-by-end* (make-hash-table :test 'equal)) (loop for gen in gens do (loop for i downfrom (1- (array-dimension *cox-segments* 0)) to 1 do (loop for seg in (loop for tegg in (aref *cox-segments* i) when (= gen (car (last tegg))) collect tegg) for j from 0 do (push seg (gethash gen *cox-segments-by-end*)) (setf (gethash seg *cox-segment-names*) (list i j)))))) (defun determine-segment-segment-relations (gens &optional (verbose t)) ;;; use '(1 0) to set priority for cox-find-reduced (let* ((red-prod nil) (ending (if (equal gens '(0)) 0 1)) (allowed nil) (relations (make-array (list (+ 1 (length (gethash 0 *cox-segments-by-end*))) (+ 1 (length (gethash ending *cox-segments-by-end*))))))) (setf *segment-repeaters* nil) ;; label first row and column (loop for seg in (gethash 0 *cox-segments-by-end*) for j from 1 do (setf (aref relations 0 j) (gethash seg *cox-segment-names*)) ) (loop for teg in (gethash ending *cox-segments-by-end*) for i from 1 do (setf (aref relations i 0) (gethash teg *cox-segment-names*))) ;; set up relations for teg.seg (loop for teg in (gethash ending *cox-segments-by-end*) for i from 1 do (loop for seg in (gethash 0 *cox-segments-by-end*) for j from 1 for prod = (cox-build-elem (append teg seg)) do (setf red-prod (cox-find-reduced prod gens )) (cond ((> (+ (length seg) (length teg)) (length red-prod)) ;; not reduced (setf (aref relations i j) 'not-red) ) ((min-length-coset-rep-p prod *parabolic*) ;; allowed product (setf (aref relations i j) 'allowed) (push (list teg seg) allowed) ) (t (setf (aref relations i j) ;; reduced but not min length coset rep (loop for leg in (find-all-segments gens red-prod ) collect (if (gethash leg *cox-segment-names*) (gethash leg *cox-segment-names*) leg))) )))) (when verbose (format t "~%Allowed products of segments:~%") (loop for pair in allowed for next-pair in (append (cdr allowed) (list nil)) do (format t " (") (cox-print-segment-name (gethash (car pair) *cox-segment-names*)) (cox-print-segment-name (gethash (second pair) *cox-segment-names*)) (format t ")") (when (not (equal (car pair) (car next-pair))) (format t "~%~%")))) (loop for pair in allowed when (equal (car pair) (second pair)) do (push (car pair) *segment-repeaters*)) (setf *allowed-pairs* allowed) (setf *allowed-hash* (make-hash-table :test 'equal)) (setf (gethash nil *allowed-hash*) (loop for i from 1 below (array-dimension *cox-segments* 0) appending (loop for seg in (aref *cox-segments* i) collect seg))) (loop for pair in *allowed-pairs* do (push (second pair) (gethash (first pair) *allowed-hash*))) ;relations )) (defun allowed-segments-with-segment (segment) (loop for pair in *allowed-pairs* when (and (member segment pair :Test 'equal) (not (equal (car pair) (second pair)))) collect (if (equal (car pair) segment) (second pair) (car pair)))) (defun cox-segment-repeaters-p (elem) (catch 'foo (loop for seg in (find-all-segments *gens* (cox-find-reduced elem)) when (member seg *segment-repeaters* :Test 'equal) do (throw 'foo t)) (throw 'foo nil))) (defun cox-segment-allowed-with-all-p (seg) (and (member seg *segment-repeaters* :Test 'equal) (= (length (loop for pair in *allowed-pairs* when (member seg pair :test 'equal) collect pair)) (length (loop for i from 1 below (array-dimension *cox-segments* 0) appending (loop for seg in (aref *cox-segments* i) collect seg)))))) (defun cox-no-repeaters (thresh) (loop for i from 0 to thresh appending (loop for elem in (gethash i *cox-quotient-hash*) when (not (cox-segment-repeaters-p elem)) collect elem))) (defun cox-find-segmented-reduced (elem) (find-all-segments *gens* (cox-find-reduced elem)) ) (defun cox-segments-to-elem (segments) (let ((new-elem *identity-element*)) (loop for seg in segments do (setf new-elem (cox-build-elem seg new-elem))) new-elem)) (defun cox-segment (size color) ;; from size^color to reduced expression (nth color (aref *cox-segments* size))) (defun cox-insert-segment (elem segment) (let ((segments (cox-find-segmented-reduced elem)) (apply t) (new-elem *identity-element*)) (if (null (car segments)) (setf new-elem (cox-build-elem segment)) (loop for seg in segments for i from 1 do (when (and (< (length segment) (length seg)) apply) (progn (setf apply nil) (setf new-elem (cox-build-elem segment new-elem)))) (setf new-elem (cox-build-elem seg new-elem)) (when (and apply (= i (length segments))) (setf new-elem (cox-build-elem segment new-elem))))) new-elem)) (defun cox-print-segment-name (name) (when name (if (= 0 (second name)) (format t "~a." (car name)) (format t "~a^~a." (car name) (second name))))) (defun cox-print-segment-decomposition (w &optional (gens '(0))) (print-segment-list (find-all-segments gens (cox-find-reduced w gens)))) (defun print-segment-list (segments) (format t "(") (loop for seg in segments do (cox-print-segment-name (gethash seg *cox-segment-names*))) (format t ")")) (defun print-segments-latex () (loop for j from 1 below (array-dimension *cox-segments* 0) do (loop for seg in (aref *cox-segments* j) do (format t "~% \\segment{}{}(") (cox-print-segment-name (gethash seg *cox-segment-names*)) (format t ") = ") (loop for i in seg do (format t "s_~a" i)) (format t " & ~a \\\\" (length seg))))) ;;;; (defun compare-partitions () (let ((part nil) (results nil)) (maphash #'(lambda (key val) (setf part (cox-partition '(0 1) (cox-find-reduced key))) (loop for u in val for diff = (sort (mapcar 'abs (unique-elems (subtract-lists part (cox-partition '(0 1) (cox-find-reduced u))))) '>) when (> (car diff) 1) do (format t "~%v= ~a part = ~a~%" key part) (format t "u= ~a u-part = ~a" u (cox-partition '(0 1) (cox-find-reduced u))))) *quotient-bruhat-hash*) )) (defun all-factored-segments-of-length (n) (let ((results nil)) (flet ((helper (tail) (push tail results))) (all-factored-segments-tester n 0 #'helper *allowed-hash* nil) results))) ;;;find all factored sequences of segments of a certain size (defun all-factored-segments-tester (n k test hash tail) (if (= n k) (funcall test tail) (loop for next-segment in (gethash (car tail) hash) when (or (> n (+ k (length next-segment))) (= n (+ k (length next-segment)))) do (all-factored-segments-tester n (+ k (length next-segment)) test hash (cons next-segment tail))))) ;;;find all factored sequences of segments of a certain size , this time with at most one segment of each type (defun all-distinct-factored-segments-of-length (n &optional (hash *allowed-hash*)) (let ((results nil)) (flet ((helper (tail) (push tail results))) (all-factored-segments-tester n 0 #'helper hash nil) results))) (defun all-distinct-factored-segments-of-length (n) (let ((results nil)) (flet ((helper (tail) (push tail results))) (all-factored-segments-tester n 0 #'helper *allowed-hash* nil) results))) (defun cox-gen-function (n segment-list ) (loop for i from 0 to n collect (length (distinct-segments-with-matched-repeaters i segment-list)))) (defun distinct-segments-with-matched-repeaters (n segment-list ) (loop for prod in (all-distinct-factored-segments-of-length n hash) when (same-lists-p segment-list (copy-list (intersect-lists (list *segment-repeaters* prod)) )) collect prod)) (defun master-maple-formula-e6 () ;;; this formula still needs to be divided by deno:=(1-t^20)* (1-t^21)* (1-t^22); (let* ((no-repeats (cox-gen-function 100 (list ))) (counter 0) (n (+ 10 (position-n no-repeats 0))) (the-list (loop for segment in *segment-repeaters* when (> 20 (length segment)) collect segment)) (gen nil)) (flet ((helper (tail) (when (allowed-product-segments tail) (incf counter) (setf gen (cox-gen-function (+ n (apply '+ (mapcar 'length tail))) tail)) (format t "~%gen[~a]:=polyfy(" counter) (print-list-maple gen) (format t ")/mul(1-t^i, i=") (print-list-maple (mapcar 'length tail)) (format t "); # ") (loop for seg in tail do (cox-print-segment-name (gethash seg *cox-segment-names*)))))) (print the-list) (all-subsequences-tester (reverse the-list) #'helper nil)))) (defun master-maple-formula-e7 () (let* ((counter 0) (n 180 ) ;; (no-repeats (cox-gen-function 180 (list ))) starts to produce zeros at 177 (the-list (loop for segment in *segment-repeaters* when (> 31 (length segment)) collect segment)) (gen nil)) (flet ((helper (tail) (when (allowed-product-segments tail) (incf counter) (format t "~%~%##") (loop for seg in tail do (cox-print-segment-name (gethash seg *cox-segment-names*))) (format t "~%gen[~a]:=polyfy(" counter) (setf gen (cox-gen-function (+ n (apply '+ (mapcar 'length tail))) tail)) (print-list-maple gen) (format t ")/mul(1-t^i, i=") (print-list-maple (mapcar 'length tail)) (format t ");")))) (print the-list) (all-subsequences-tester (reverse the-list) #'helper nil)))) (defun master-maple-formula () (let* ((counter 0) (the-list nil) (all-allowed-repeaters nil) (gen nil)) (loop for segment in (reverse *segment-repeaters*) do (if (cox-segment-allowed-with-all-p segment) (push (gethash segment *cox-segment-names*) all-allowed-repeaters) (push (gethash segment *cox-segment-names*) the-list))) (format t "~%~%## Cut Here and Paste into Maple to Simplify:") (format t "~%~%## Denominator corresponding to parts allowed with all: ") (format t "~%~%deno[~a,~a]:= mul(1-t^i, i=" (caar *type*) (cdr (car *type*))) (print-list-maple (mapcar 'cpart-size all-allowed-repeaters)) (format t "):") (flet ((helper (tail) (when (allowed-cpart-p tail *allowed-cpart-hash*) (incf counter) (format t "~%~%## Repeaters: ~a" tail) (format t "~%gen[~a]:=polyfy(" counter) (setf gen (cpart-rank-gen-function-with-required-repeaters tail)) (print-list-maple (car gen)) (format t ")/mul(1-t^i, i=") (print-list-maple (mapcar 'cpart-size tail)) (format t "):")))) ;(print the-list) (all-subsequences-tester (reverse the-list) #'helper nil)) (format t "~%~%## End Cut:"))) (defun master-maple-formula-max-k-size (k) (let* ((counter 0) (the-list (loop for part in *repeating-parts* when (> k (cpart-size part)) collect part)) (gen nil)) (flet ((helper (tail) (when (allowed-cpart-p tail *allowed-cpart-hash*) (incf counter) (format t "~%~%## ~a" tail) (format t "~%gen[~a]:=polyfy(" counter) (setf gen (cpart-rank-gen-function-with-required-repeaters tail)) (print-list-maple (car gen)) (format t ")/mul(1-t^i, i=") (print-list-maple (mapcar 'cpart-size tail)) (format t "):")))) (print the-list) (all-subsequences-tester (reverse the-list) #'helper nil)))) (defun grind-affine-partition-gf (type n thresh) (grind-affine-partitions type n thresh) (if (< (array-dimension *cox-segments* 0) thresh) (master-maple-formula ) (format t "~%~%Rerun with higher thresh value, some segments not found.~%"))) (defun allowed-product-segments (segment-list) (catch 'foo (loop for seg in segment-list for teg in (cdr segment-list) when (not (member teg (gethash seg *allowed-hash*) :test 'equal)) do (throw 'foo nil)) (throw 'foo t))) (defun allowed-segments-only-p (elem allowed) (or (equal elem *identity-element*) (catch 'foo (loop for segment in (find-all-segments *gens* (cox-find-reduced elem)) when (not (member segment allowed :Test 'equal)) do (throw 'foo nil)) (throw 'foo t)))) (defun avoiding-segments-p (elem disallowed) (catch 'foo (loop for segment in (find-all-segments *gens* (cox-find-reduced elem)) when (member segment disallowed :Test 'equal) do (throw 'foo nil)) (throw 'foo t))) (defun cox-sort-by-length (elem-list) (let ((elem-hash (make-hash-table :test 'equal))) (loop for elem in elem-list do (push elem (gethash (cox-length elem) elem-hash))) elem-hash)) (defun nr-partitions-allowed-with-segments (segment-list) (let* ((allowed (intersect-lists (loop for segment in segment-list collect (allowed-segments-with-segment segment)))) (hash (cox-sort-by-length (loop for elem in *no-repeat* when (allowed-segments-only-p elem allowed) collect elem)))) (loop for i from 0 to *thresh* collect (length (gethash i hash))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun a-segment (i j) ;;; 0<=i <= n, 1<=j<=n (when (= j 0) (format t "wrong j")) (append (loop for a downfrom i to 1 collect a) (loop for b from (- (1+ *n*) j) below *n* collect b) (list 0))) (defun a-pairs (n) (sort (loop for i from 0 to n appending (loop for j from 1 to n collect (list i j))) 'smaller-sum-p)) (defun check-a-segment-rels () (let ((pairs (a-pairs (1- *n*)))) (loop for a in pairs for ca = (a-segment (first a) (second a)) do (loop for b in pairs for cb = (a-segment (first b) (second b)) when (not (equal (my-test a b (1- *n*)) (consecutive-segments-p ca cb))) do (format t "~%New Relation: ~a ~a" a b ) (format t "~% my-test: ~a min-length:~a" (my-test a b (1- *n*)) (consecutive-segments-p ca cb)))))) (defun list-a-segment-rels (n) (let ((pairs (a-pairs n))) (loop for a in pairs for ca = (a-segment (first a) (second a)) collect (loop for b in pairs for cb = (a-segment (first b) (second b)) when (consecutive-segments-p cb ca) collect (list b a))))) (defun my-test (a b n) (let ((cb (a-segment (first b) (second b))) (ca (a-segment (first a) (second a)))) (or (and (< n (length ca) ) (<= (first a) (first b)) (<= (second a) (second b))) (and (< n (length cb) ) (< (first a) (first b)) (<= (second a) (second b))) (and (< (first a) (first b)) (< (second a) (second b)))))) (defun consecutive-segments-p (ca cb) (and (= (+ (length ca) (length cb)) (cox-length (cox-build-elem (append ca cb)) )) (min-length-coset-rep-p (cox-build-elem (append ca cb)) *parabolic*))) (defun find-unique-segment-types () (unique-elems (loop for i from 1 to (* 2 (1- *n*)) appending (loop for seg in (aref *cox-segments* i) collect (colapse-zeros (cox-build-coroot seg)))))) (defun find-unique-segment-product-types () (let ((results nil)) (maphash #'(lambda (key val) (setf results (unique-elems (append results (loop for seg in val collect (colapse-zeros (cox-build-coroot (append key seg)))))))) *allowed-hash*) results)) (defun segment-product-hash () (setf *segment-product-hash* (make-hash-table :test 'equal)) (maphash #'(lambda (key val) (loop for seg in val do (push (append key seg) (gethash (colapse-zeros (cox-build-coroot (append key seg))) *segment-product-hash*)))) *allowed-hash*) *segment-product-hash*) (defun mitchell-palindromic (i j k) (let ((n (1- *n*))) (cond ((and (= i 0) (= (- n j) (mod k n))) (cox-build-elem (append (a-segment i j) (loop for i from 1 to k appending (a-segment 1 n))))) ((and (= j 1) (= (- n i 1) (mod k n))) (cox-build-elem (append (a-segment i j) (loop for i from 1 to k appending (a-segment n 1))))) (t (format t "~% Mitchell index not correct: ~a" (list i j k)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; from colored.partitions.lisp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Colored partitions arrise in the affine grassmannians ;;; and Coxeter.lisp. These partitions are determined by pairwise adacency rules in *allowed-cpart-hash*. ;; colored partitions are represented by lists of cons cells (list (list lambda_1 c_1) (list lambda_2 c_2) ...) ;;; with the lambda_i's weakly increasing and the c_i's are the colors (defun grind-affine-partitions (type n thresh) (make-affine-quotient type n thresh (loop for i from 1 to n collect i)) (setf *gens* (if (member type (list 'affine-b 'affine-d :test 'equal)) '(1 0) '(0))) (grind-cox-partitions *gens* nil) (weak-order-colored-parts) (setf *gen-young-lattice* (make-hash-table :test 'equal)) (determine-segment-segment-relations *gens* nil) (setup-allowed-segments-to-allowed-cparts)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;(setf *allowed-cpart-hash* (make-hash-table :test 'equal)) ;;; the following functions depend on the representation of a colored partition. Otherwise, it is just a list of "parts". (defun cpart-color (a) (second a)) (defun cpart-size (a) (car a)) (defun cpart-length (cpart) ;;; size of the colored partition in cpart (apply '+ (loop for part in cpart collect (cpart-size part)))) (defun compare-cparts (a b) ;;; for sorting order (cond ((null a) t) ((null b) nil) ((< (cpart-size a) (cpart-size b)) t) (t (and (= (cpart-size a) (cpart-size b)) (< (cpart-color a) (cpart-color b)))))) (defun allowed-cpart-p (cpart &optional (allowed-hash *allowed-cpart-hash*)) ;;; assumes cpart is sorted in increasing order (catch 'foo (loop for p in cpart for q in (cdr cpart) when (not (member q (gethash p allowed-hash) :test 'equal)) do (throw 'foo nil)) (throw 'foo t))) ;;;find all allowed colored partions of a certain size (defun all-allowed-cparts-of-length (n &optional (allowed-hash *allowed-cpart-hash*)) (let ((results nil)) (flet ((helper (tail) (push tail results))) (all-allowed-cparts-tester-given-length n 0 #'helper allowed-hash nil) results))) (defun all-allowed-cparts-tester-given-length (n k test hash tail) (if (= n k) (funcall test tail) (loop for next-cpart in (gethash (car tail) hash) when (or (> n (+ k (length next-cpart))) (= n (+ k (length next-cpart)))) do (all-allowed-cparts-tester-given-length n (+ k (length next-cpart)) test hash (cons next-cpart tail))))) (defun all-allowed-cparts-tester (test hash tail) ;;; warning won't terminate if hash has repeaters!!! (funcall test (reverse tail)) (loop for next-cpart in (gethash (car tail) hash) do (all-allowed-cparts-tester test hash (cons next-cpart tail)))) (defun restricted-cpart-hash (cpart-list &optional (repeats-p t)) (let ((hash (make-hash-table :test 'equal))) (maphash #'(lambda (key val) (when (member key cpart-list :Test 'equal) (setf (gethash key hash) (intersect-lists (list cpart-list (loop for cpart in val when (or repeats-p (not (equal cpart key))) collect cpart)))))) *allowed-cpart-hash*) hash)) ;;; since these cparts only depend on pairwise adjacent rules, their generating function depends on the ;;;; finite gen function of distinct allowed cpartitions dived by product of (1-t^i) for each i which is allowed to repeat. (defun cpart-rank-gen-function-with-required-repeaters (required-repeaters) (when (allowed-cpart-p required-repeaters *allowed-cpart-hash*) (let ((restricted-hash (restricted-cpart-hash (loop for part in *non-repeating-parts* when (allowed-cpart-p (sort (copy-list (cons part required-repeaters)) 'compare-cparts) *allowed-cpart-hash*) collect part) nil)) (n (cpart-length required-repeaters)) (counter-hash (make-hash-table :test 'equal))) (flet ((helper (tail) ;(print tail) ;;debug (if (gethash (+ (cpart-length tail) n) counter-hash) (incf (gethash (+ (cpart-length tail) n) counter-hash)) (setf (gethash (+ (cpart-length tail) n) counter-hash) 1)))) (all-allowed-cparts-tester #'helper restricted-hash nil) ;; no length constraint (list (loop for i from 0 to (find-supremum (hash-keys counter-hash) '>) collect (if (gethash i counter-hash) (gethash i counter-hash) 0)) (loop for part in required-repeaters collect (cpart-size part))))))) (defun setup-allowed-segments-to-allowed-cparts () (setf *allowed-cpart-hash* (make-hash-table :test 'equal)) (setf *non-repeating-parts* nil) (setf *repeating-parts* nil) (loop for pair in *allowed-pairs* for part1 = (gethash (first pair) *cox-segment-names*) for part2 = (gethash (second pair) *cox-segment-names*) do (push part2 (gethash part1 *allowed-cpart-hash*)) (when (equal part1 part2) (push part1 *repeating-parts*))) (maphash #'(lambda (key val) (when key (push key (gethash nil *allowed-cpart-hash*))) ;;; everything can follow nil (when (not (member key *repeating-parts* :Test 'equal)) (push key *non-repeating-parts*))) *allowed-cpart-hash*) (setf *repeating-parts* (sort *repeating-parts* 'compare-cparts)) (setf *non-repeating-parts* (sort *non-repeating-parts* 'compare-cparts))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;Generalized young's lattice ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun young-interval (cpartition) (let ((hash (make-hash-table :test 'equal))) (rec-young-interval (list cpartition) hash) hash)) (defun rec-young-interval (cpart-list hash) (when cpart-list (let ((new-cparts nil)) (loop for cpart in cpart-list do (setf (gethash cpart hash) (young-covers cpart)) (setf new-cparts (append (gethash cpart hash) new-cparts))) (rec-young-interval (unique-elems new-cparts) hash)))) (defun young-covers (cpart) (when (null (gethash cpart *gen-young-lattice*)) (setf (gethash cpart *gen-young-lattice*) (cpart-covers cpart))) (gethash cpart *gen-young-lattice*)) (defun cpart-covers (cpart) (when cpart (let ((covers nil)) (loop for part in cpart for i from 0 when (or (= 0 i) (not (equal part (nth (1- i) cpart)))) ;; only check corners do (loop for lower-part in (gethash part *colored-parts-order*) for new-cpart = (append (first-n i cpart) (cons lower-part (nthcdr (1+ i) cpart))) when (allowed-cpart-p new-cpart) do (push new-cpart covers))) (when (= 1 (caar cpart)) (push (cdr cpart) covers)) covers))) (defun cpart-poincare (elem &optional (palindrom-steps 0)) (if (equal elem (list nil)) '(1) (reverse (cons 1 (cpart-poincare-helper (1- (cpart-length elem)) (young-covers elem) palindrom-steps))))) (defun cpart-poincare-helper (index elem-list &optional (palindrom-steps 0)) (let ((covered-elems nil)) (when (and elem-list (or (> 1 palindrom-steps) (= 1 (length elem-list)))) (loop for elem in elem-list do (loop for covered-elem in (young-covers elem) when (not (member covered-elem covered-elems :test 'equal)) do (push covered-elem covered-elems))) (cons (length elem-list) (cpart-poincare-helper (1- index) covered-elems (1- palindrom-steps)))))) (defun cpart-palindromic-p (elem) (let ((poincare (cpart-poincare elem (1- (length *one-elem-index*))))) ;;;; *one-elem-index* = list of ranks with 1 elem (and (= (length poincare) (1+ (cpart-length elem))) ;;; this is a shortcut for when the break point is up near the max so we don't build the whole poincare poly (symmetric-list-p poincare)))) ;; in fact we only need to test symmetric when it actually is symmetric by the shortcut above (defun thin-interval-p (elem) (let* ((depth (length *one-elem-index*)) ;;;; *one-elem-index* = list of ranks with 1 elem (poincare (cpart-poincare elem (1- depth)))) (and (= (length poincare) (1+ (cpart-length elem))) ;;; this is a shortcut for when the break point is up near the max so we don't build the whole poincare poly (or (< (length poincare) depth) (equal (first-n depth poincare) (loop for i from 1 to depth collect 1)))))) (defun grow-thin-cparts (part-thresh) (setf *thin-cparts* (make-array (list (1+ part-thresh)))) (push nil (aref *thin-cparts* 0)) (loop for part in (append *non-repeating-parts* *repeating-parts*) when (and part (thin-interval-p (list part))) do (push (list part) (aref *thin-cparts* 1))) (loop for i from 2 to part-thresh do (loop for cpart in (aref *thin-cparts* (1- i)) do (loop for new-part in (gethash (car (last cpart)) *allowed-cpart-hash*) for new-cpart = (append cpart (list new-part)) when (thin-interval-p new-cpart) do (push new-cpart (aref *thin-cparts* i))))) *thin-cparts*) (defun grow-thin-cparts-from (start-cparts) (loop for cpart in start-cparts appending (loop for new-part in (gethash (car (last cpart)) *allowed-cpart-hash*) for new-cpart = (append cpart (list new-part)) when (thin-interval-p new-cpart) collect new-cpart ))) (defun setup-extra-thin-cparts () (setf *extra-thin-cparts* (make-hash-table :test 'equal)) (push nil (gethash 0 *extra-thin-cparts*)) (loop for part in (append *non-repeating-parts* *repeating-parts*) when (and part (thin-interval-p (list part))) do (push (list part) (gethash 1 *extra-thin-cparts*)))) (defun grow-extra-thin-cparts (i) (when (and (null (gethash i *extra-thin-cparts*)) (> i 1)) (setf (gethash i *extra-thin-cparts*) (loop for cpart in (grow-extra-thin-cparts (1- i)) appending (loop for new-part in (gethash (car (last cpart)) *allowed-cpart-hash*) for new-cpart = (append cpart (list new-part)) when (extra-thin-cpart-p new-cpart) collect new-cpart )))) (gethash i *extra-thin-cparts*)) (defun extra-thin-cpart-p (cpart) (and (thin-interval-p cpart) (not (double-allowed-bruhat-split-p cpart)))) (defun grind-all-thin-cparts (type n thresh) (let ((palindromics nil) (poincare-break 1)) (make-affine-quotient type n thresh (loop for i from 1 to n collect i)) (create-quotient-bruhat-hash) (grind-cox-partitions *gens*) (weak-order-colored-parts) (setf *gen-young-lattice* (make-hash-table :test 'equal)) (determine-segment-segment-relations *gens*) (setup-allowed-segments-to-allowed-cparts) ;;;; (setup-extra-thin-cparts) (setf *long-chains* nil) (format t "~%~%In Type: ~a" *type*) (grow-extra-thin-cparts 7) (format t "~% Extra Thin colored partitions up to length 7: ~%") (print-sorted-hash *extra-thin-cparts* `<) (format t "~% Checking which Extra Thin colored partitions up to len 7 are palindromic: ~%") (loop for i from 0 to 7 do (setf palindromics nil) (loop for cpart in (gethash i *extra-thin-cparts*) do (if (cox-palindromic-p (cpart-to-cox-elem cpart) *quotient-bruhat-hash* *cox-quotient-hash* ) (push cpart palindromics) (setf poincare-break (max poincare-break (poincare-symmetry-break-point (cpart-to-cox-elem cpart) *quotient-bruhat-hash* *cox-quotient-hash* ))))) (format t "~% ~a Parts: ~a" i palindromics)) (format t "~%Max-Poincare-break-point:~a achived at: ~a" poincare-break (loop for elem in *long-chains* collect (cox-elem-to-colored-partition elem))) (format t "~%First-break-point-at-length:~a" (length *one-elem-index*)))) (defun checking-bruhat-covers (k) (format t "~% Checking Bruhat covers:") (loop for cpart in (aref *thin-cparts* k) do (format t "~% ~a: ~a" cpart (cpart-bruhat-covers cpart))) (setf *remaining-to-check* (loop for cpart in (aref *thin-cparts* k) when (not (double-allowed-bruhat-split-p cpart)) collect cpart)) (format t "~%~% Extra Thin colored partitions of length ~a remaining to check: ~a " k (length *remaining-to-check*)) (print *remaining-to-check* ) nil) (defun cpart-bruhat-covers (cpart) (let ((cox-elem (cpart-to-cox-elem cpart))) (when (null (gethash cox-elem *quotient-bruhat-hash*)) (setf (gethash cox-elem *quotient-bruhat-hash*) (cox-covered-elems cox-elem *parabolic*))) (loop for elem in (gethash cox-elem *quotient-bruhat-hash*) collect (cox-elem-to-colored-partition elem)))) (defun double-allowed-bruhat-split-p (cpart) (let ((last-part (last cpart)) (covered-b-cparts (cpart-bruhat-covers cpart))) (< 1 (length (loop for elem in covered-b-cparts when (equal last-part (last elem)) collect elem))))) ;;;; testing palindromic elements have isomorphic bruhat and young's lattice intervals: (defun test-bruhat-and-young-interval-isomorphic (cpart) (cpart-b-y-test (list cpart))) (defun cpart-b-y-test (elem-list) (let ((covered-elems nil)) (or (equal elem-list '(NIL)) (catch 'foo (loop for elem in elem-list for y-covers = (young-covers elem) for b-covers = (cpart-bruhat-covers elem) do (if (not (same-lists-p y-covers b-covers 'equal)) (throw 'foo nil) (setf covered-elems (unique-elems (append y-covers covered-elems))))) (throw 'foo (cpart-b-y-test covered-elems)))))) (defun test-bruhat-young-palindromic-conjecture (type n thresh) (grind-affine-partitions type n thresh) (create-quotient-bruhat-hash) (format t "~%Testing palindromics:~%") (setf *palindromics* (cox-find-palindromics *quotient-bruhat-hash* *cox-quotient-hash* *gens*)) (format t "~%~%Trouble with Bruhat-Young's lattice isomorphism: ~a" (loop for pal in *palindromics* when (not (test-bruhat-and-young-interval-isomorphic (cox-elem-to-colored-partition pal))) collect pal))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; tools from perms.lisp, polys.lisp, mat.lisp ;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; Hash table functions. (defun print-hash (hash) (maphash #'(lambda (key val) (format t "~%~a:: ~a" key val)) hash)) (defun print-hash-file (hash file) (with-open-file (stream file :direction :output :if-exists :append) (maphash #'(lambda (key val) (format stream "~%~a:: ~a" key val)) hash))) ;;nice app: (print-sorted-hash *perm-hash* #'lex-order) (defun print-sorted-hash (hash sort-fn) (let ((keys nil)) (maphash #'(lambda (key val) (push key keys)) hash) (loop for key in (sort keys sort-fn) do (format t "~%~a: ~a~%" key (gethash key hash))))) (defun hash-keys (hash) (let ((keys nil)) (maphash #'(lambda (key val) (push key keys)) hash) keys)) (defun hash-vals (hash) (let ((vals nil)) (maphash #'(lambda (key val) (push val vals)) hash) vals)) (defun hash-equal (hash1 hash2 &optional (equal-test 'equal)) (when (same-lists-p (hash-keys hash1) (copy-list (hash-keys hash2)) equal-test) (catch 'foo (maphash #'(lambda (key val) (when (not (funcall equal-test val (gethash key hash2))) (print val) (print 'val-not-equal) (throw 'foo nil))) hash1) (throw 'foo t) ))) ;;;; polynomial and list functions (defun colapse-zeros (alist) (let ((new (loop for i in alist for j in (cdr alist) when (not (and (= 0 i) (= 0 j))) collect j))) (cons (car alist) new))) (defun carefully-remove-zeros (l) (reverse (nthcdr (catch 'foo (loop for i in (reverse l) for num from 0 do (when (not (= 0 i)) (throw 'foo num))) (throw 'foo (length l))) (reverse l)))) (defun print-list-maple (alist) (if (null alist) (format t "[]") (progn (format t "[~a" (car alist)) (loop for i in (cdr alist) do (format t ",~a" i)) (format t "]")))) (defun add-lists (list1 list2) (append (loop for i in list1 for j in list2 collect (+ i j)) (when (> (length list1) (length list2)) (nthcdr (length list2) list1)) (when (< (length list1) (length list2)) (nthcdr (length list1) list2)))) (defun subtract-lists (list1 list2) (append (loop for i in list1 for j in list2 collect (- i j)) (when (> (length list1) (length list2)) (nthcdr (length list2) list1)))) (defun find-minimum (list) (find-supremum list #'<)) (defun find-supremum (list &optional (test #'>)) "Returns the first element of LIST by the partial order implied by TEST." ;;; first elem. must be non nil. Others can be nil. (loop with max = (car list) for e in (cdr list) when e do (when (funcall test e max) (setq max e)) finally (return max))) (defun first-n (n l) (when (and l (> n 0)) (cons (car l) (first-n (1- n) (cdr l))))) (defun unique-elems (l) (cond ((null (cdr l)) l) ((member (car l) (cdr l) :test #'equal) (unique-elems (cdr l))) (t (cons (car l) (unique-elems (cdr l)))))) (defun symmetric-list-p (alist) (equal alist (reverse alist))) (defun symmetry-break-point (alist) (let ((break nil)) (loop for i in alist for j in (reverse alist) for k from 0 while (equal i j) finally (when (not (equal i j)) (setf break k))) break)) (defun same-lists-p (list1 list2 &optional (test #'equal)) ;;; this is side-affecting list2 (let ((test-list (copy-list list2))) (when (= (length list1) (length list2)) (catch 'bug (loop for item in list1 do (let ((t-elem (member item test-list :test test))) (if t-elem (setf (first t-elem) nil) (throw 'bug nil)))) (throw 'bug (null (loop for elem in test-list appending (when elem elem)))))))) (defun increasing-p (l) ;;weakly increasing (cond ((null l) nil) ((= 1 (length l)) t) ((<= (car l) (cadr l)) (increasing-p (cdr l))) (t nil))) (defun position-n (perm n) (let ((pos-n nil)) (loop for i in perm for j from 0 ;; 0 based until (= (abs i) n) finally (setf pos-n j)) pos-n)) (defun count-matches (i word) (let ((count 0)) (loop for j in word when (equal i j) do (incf count)) count)) (defun rev-lex-order (list1 list2);;;assuming sums equal (let ((a (reverse (carefully-remove-zeros list1))) (b (reverse (carefully-remove-zeros list2)))) (cond ((> (length a) (length b)) t) ((< (length a) (length b)) nil) (t (catch 'foo (loop for x in a for y in b do (cond ((< x y) (throw 'foo nil)) ((> x y) (throw 'foo t)))) (throw 'foo t)))))) ;;; if equal return t ;;note changed from nil for new.products.lisp (defun lex-order (list1 list2);;;assuming degrees equal (let ((a (carefully-remove-zeros list1)) (b (carefully-remove-zeros list2))) (catch 'foo (loop for x in a for y in b do (cond ((> (abs x) (abs y)) (throw 'foo nil)) ((< (abs x) (abs y)) (throw 'foo t)) ((< x y) (throw 'foo nil)) ((> x y) (throw 'foo t)))) (cond ((< (length a) (length b)) t) ((> (length a) (length b)) nil) (t (throw 'foo t)))))) (defun lex-order-lists (list1 list2) (when list1 list2 (catch 'foo (loop for i in list1 for j in list2 do (cond ((< i j) (throw 'foo t)) ((> i j) (throw 'foo nil)))) (throw 'foo (< (length list1) (length list2)))))) (defun lex-order-lists-of-lists (list1 list2) (when list1 list2 (catch 'foo (loop for i in list1 for j in list2 do (cond ((equal i j) nil) ((lex-order-lists i j) (throw 'foo t)) ((lex-order-lists j i) (throw 'foo nil)))) (throw 'foo (< (length list1) (length list2)))))) ;;;;;; (defun all-subsequences-tester (the-list test tail) ;;; formerly all-subset-tester (if (null the-list) (funcall test tail) (progn (all-subsequences-tester (cdr the-list) test (cons (car the-list) tail)) (all-subsequences-tester (cdr the-list) test tail)))) (defun all-partitions-tester (n-parts minvalue maxvalue test tail) (if (= 0 n-parts) (funcall test tail) (loop for a from minvalue to maxvalue do (all-partitions-tester (1- n-parts) a maxvalue test (cons a tail))))) (defun list-all-partitions (n-parts maxvalue) (let ((results nil)) (flet ((helper (tail) (push tail results))) (all-partitions-tester n-parts 0 maxvalue #'helper nil)) results)) (defun list-all-partitions-of-n (n n-parts minvalue) (let ((results nil)) (flet ((helper (tail) (when (= n (apply '+ tail)) (push tail results)))) (all-partitions-tester n-parts minvalue n #'helper nil)) results)) (defun intersect-lists (list-of-lists &optional (eq-fn #'equal)) (let ((start (car list-of-lists)) (intersection nil)) (loop for i in start do (when (= 1 (apply #'* (loop for l in (cdr list-of-lists) collect (if (member i l :test eq-fn) 1 0)))) (push i intersection))) intersection))