Here I attempt a synthesis of my discoveries, mostly from web searches but some by thinking and computer exploration. This is organized around the Scheme code. I use “tandem recursion” for these reasons. The function G takes a list of tools (each a Scheme value) for a Clifford algebra of some degree and returns a similar list for the Clifford algebra of next higher degree. Given the tools for Cliff(n, K) it returns the tools for Cliff(n+1, K) (Here “Cliff(n, K)” denotes the nth order Clifford algebra over field K.) The field is determined by the Scheme value named field. Cliff(0, K) is isomorphic to K. In these exercises K is the reals but the function G does not depend on this. See “IndCliff” here for a newer and more complete version of this. Here is a simpler version limited to positive definite quadratic forms.

The function GG relies on G and takes arguments such as (GG (list + - -)) to yield a Clifford algebra based on a vector space with a quadratic form of signature <+, −, −>.

A tool list has 18 items as follows:
 + C × C → C Addition of two cns(Clifford numbers) − C × C → C Subtraction of two cns * C × C → C Multiplication of two cns zero C The additive identity one C The multiplicative identity / C → C Multiplicative inverse (can fail and return #f) = C × C → bool Comparison of two cns for equality Cr → C Sample generator alpha C → C λx.α(x) bar C → C λx. tr C → C λx.x† rp C → K real part: λx. sm K × C → C scalar multiply mag2 C → K Euclidean distance squared, taking C as Euclidean space basis list of basis elements for V, expressed as elements of C real? C → bool is cn real? If so as field element. V? C → bool is this cn in V? If so as list of n reals. Q C → K quadratic form extended to C
Following the tandem recursion we unpack the resulting list of tools and give each a name in the top level name space: C+, C−, C*, etc.

The code below is designed to test the following ideas. This project is very incomplete. A Clifford algebra can be built on a vector space with quadratic form Q that is not positive definite although Clifford did not consider that case. The rules for multiplying basis elements together are modified as follows:
If Q(γj) < 0 then γjγj = 1.
If Q(γj) > 0 then γjγj = −1.
Almost all of the theory remains intact with these modifications. The Clifford group of the modified Clifford algebra can model the rotations of Lorentz space of various signatures. For signature (− + + +) we model the isometries of a uniformly negatively curved 3 space. The floating point matrices given below were randomly generated by this C code.

For signature <+, −, ...> where γ0γ0 = 1, then (γ0 + γ1)2 = 0; a whole new sort of zero divisor. (γ0 + γ1) is a null vector in V so it figures! Now we have zero divisors in the Clifford group!

```(define (G k f)
(apply (lambda (+ - * zero one / = Cr alpha bar tr rp sm mag2 basis real? V? Q)
(let* ((p (positive? (k 1)))(*+ (if p + -))(/+ (if p - +)))
(list
(lambda (a b) (cons (+ (car a)(car b))(+ (cdr a)(cdr b)))) ; +
(lambda (a b) (cons (- (car a)(car b))(- (cdr a)(cdr b)))) ; - (subtraction)
(lambda (a b) (cons (*+ (* (car a)(car b))(* (cdr a)(alpha (cdr b))))
(+ (* (car a)(cdr b))(* (cdr a)(alpha (car b)))))) ; *
(cons zero zero) ; zero
(cons one zero) ; one

(lambda (x) (let* ((a (car x))(b (cdr x))(ai (/ a))) ; inverse
(if ai (let* ((aib (* ai b))(c (/ (/+ a (* b (alpha aib))))))
(and c (cons c (- zero (* aib (alpha c))))))
(let ((bi (/ b)))
(and bi (let* ((bia (* bi a))(d (/ (/+ (* (alpha a) bia) (alpha b)))))
(and d (cons (alpha (* bia d)) (- zero d)))))))))
(lambda (a b) (and (= (car a)(car b)) (= (cdr a)(cdr b)))) ; =
(lambda () (cons (Cr) (Cr))) ; Cr
(lambda (x) (cons (alpha (car x)) (- zero (alpha (cdr x))))) ; alpha
(lambda (x) (cons (bar (car x)) (- zero (tr (cdr x))))) ; bar
(lambda (x) (cons (tr (car x)) (bar (cdr x)))) ; tr
(lambda (x) (rp (car x))) ; rp
(lambda (s x) (cons (sm s (car x)) (sm s (cdr x)))) ; sm
(lambda (x) (fa (mag2 (car x)) (mag2 (cdr x)))) ; mag2
(cons (cons zero one) (map (lambda (x) (cons x zero)) basis)) ; basis
(lambda (x) (and (real? (car x)) (= (cdr x) zero))) ; real?
(lambda (x) (let ((q (V? (car x)))(u (cdr x)))
(and q (real? u) (cons (rp u) q)))) ; in V?
(lambda (x) (k (Q (car x)) (Q (cdr x)))) ; quadratic form
))) f))

(define (Do n p) (if (> n 0) (let ((u (- n 1))) (p u) (Do u p))))

; The following function grc4 is a crypto algorithm
; used here merely as a source of quality random numbers.
(define (grc4 key)(let ((s (make-string 256))(i 0)(j 0))
(Do 256 (lambda(n) (string-set! s n (integer->char n))))
(let ((len (string-length key))(j 0))
(Do 256 (lambda (k) (let ((i (- 255 k)))
(set! j (modulo (+ j (char->integer (string-ref s i))
(char->integer (string-ref key (modulo i len)))) 256))
(let ((t (string-ref s i))) (string-set! s i (string-ref s j))
(string-set! s j t))))))
(lambda (n)(let ((v 0)) (Do n (lambda (dm)
(set! i (if (= i 255) 0 (+ i 1)))
(let* ((a (string-ref s i))(A (char->integer a)))
(set! j (modulo (+ j A) 256))
(let* ((b (string-ref s j))(B (char->integer b)))
(string-set! s i b)(string-set! s j a)
(set! v (+ (* 256 v) (char->integer
(string-ref s (modulo (+ A B) 256))))))))) v))))

(define Kr (let ((ig (grc4 "vjoe"))) (lambda ()(/ (ig 1)(+ 1 (ig 1))))))
; (Kr) returns a random field element, here a real.
(define reals (let ((i (lambda (x) x))(s (lambda (x) (* x x))))
(list + - * 0 1 (lambda (x) (if (zero? x) #f (/ x)))
= Kr i i i i * s '() i (lambda (x) (and (zero? x) '())) s)))

(define field reals) ; which field to use
(define (GG sig) (if (null? sig) field (G (car sig) (GG (cdr sig)))))

(define fa (car field)) ; field addition
(define sig (list - - - -)) ; change this to control signature
; (define sig (list + - - -)) ; this for Minkowski space
(define P (GG sig)) ; Produce Cl(sig)
; Now unpack the tools.
(define C+ (car P)) ; Add Clifford numbers
(define -- (cadr P)) ; subtract
(define C* (caddr P)) ; *
(define C0 (cadddr P)) ; The 0 Clifford number
(define P1 (cddddr P)) ; rest of tools
(define C1 (car P1)) ; The 1 Clifford number
(define C/ (cadr P1)) ; Multiplicative inverse
(define C= (caddr P1)) ; equality
(define Cr (cadddr P1)) ; sample generator
(define P2 (cddddr P1)) ; rest of tools
(define Ca (car P2)) ; principle involution; alpha in some texts.
(define tr (caddr P2)) ; transpose
(define rp (cadddr P2)) ; real part
(define P3 (cddddr P2)) ; rest of tools
(define sm (car P3)) ; scalar multiply
(define mag2 (cadr P3)) ; Euclidean magnitude squared
(define basis (caddr P3)) ; list of basis elements of V
(define Creal? (cadddr P3)) ; is this clifford number a real?
(define P4 (cddddr P3)) ; rest of tools
(define V? (car P4)) ; is this clifford number in V? if so as list of reals.

(define (sp x y) (rp (C* (tr x) y)))
(define (even a)(sm 1/2 (C+ a (Ca a)))) ; even part of Clifford number
(define (odd a)(sm 1/2 (-- a (Ca a)))) ; odd part of Clifford number
(define (Sr b) (lambda () (let Vr ((x b)) (if (null? x) C0
(C+ (sm (Kr) (car x)) (Vr (cdr x)))))))
(define Vr (Sr basis)) ; returns a random member of V.

(define g0 (car basis)) ; individual Clifford number basis elements for V in C.

(define (ip a b) (rp (C* (bar a) b)))

(define (transpose x) (if (null? (car x)) '()
(cons (map car x) (transpose (map cdr x)))))

(define (mm x y) (map (lambda (x) (map (lambda (y)
(let ip ((a x)(b y)) (if (null? a) 0 (+ (* (car a) (car b))
(ip (cdr a)(cdr b)))))) y)) x))

(define (turn v x) (C* x (C* v (Ca (C/ x)))))
(define (Cg? x) (and (not (zero? (sp x x))) (not (not (V? (turn (Vr) x))))))

(define (Om cn) (map (lambda (x) (V? (turn x cn))) basis))
```
; Om above forms a square orthogonal matrix depicting the rotation if cn is in the Clifford group.
; nc below transforms a cn from one basis in V to another.
```(define (nc om cn) (let ((bp (map (lambda (or) (let sl ((sum C0)(o or)(b basis))
(if (null? o) sum (sl (C+ sum (sm (car o)(car b))) (cdr o)(cdr b))))) om)))
(let ev ((cn cn)(bp bp)) (if (null? bp) (sm cn C1)
(C+ (ev (car cn)(cdr bp)) (C* (ev (cdr cn) (cdr bp)) (car bp)))))))

; (let ((a (Vr))(b (Vr))) (= (* (Q a)(Q b)) (Q (C* a b)))) => #t

(define (ccfc op) (mag2 (let ((a (Cr))(b (Cr))) (-- (op (nc om a)(nc om b))(nc om (op a b))))))
(define (cfc op) (mag2 (let ((a (Cr))) (-- (op (nc om a))(nc om (op a))))))
(define (ccfk op) (let ((a (Cr))(b (Cr))) (- (op (nc om a)(nc om b))(op a b))))
(define (cfk op) (let ((a (Cr))) ( - (op (nc om a)) (op a))))
(define (fc c) (mag2 (-- c (nc om c))))
(define (kcfc op) (let ((s (Kr))(a (Cr))) (mag2 (-- (nc om (op s a)) (op s (nc om a))))))
(define zx (C+ (sm 2/3 C1)(C* g2 (C+ (sm 1/2 g0) g1))))
; (Cg? zx) => #t
(define om (Om zx))
; (map ccfc (list C+ -- C*)) => (0 0 0)
; (map cfc (list C/ Ca bar tr even odd)) => (0 0 0 0 0 0)
; (map ccfk (list sp ip)) => (0 0)
; (map cfk (list rp Q)) => (0 0)
; (cfk mag2) => 0 only for negative definite Q.
```
; The above shows that 13 miscellaneous functions transform as they should. They are coördinate free!
```; om, below, is currently broken.
(define om (cond ((or (= n 0) (= n 4)) '( ; sig = 0 or 15
(  0.632029912285030 -0.345479757766476 -0.594744514125551  0.357016652088046)
( -0.592369871660068  0.170849658106720 -0.289145172937079  0.732327384740895)
( -0.007476840833518 -0.674616965961234  0.622259647858576  0.397025158819098)
( -0.499580045615879 -0.629560227885855 -0.418887768419743 -0.422618900376064)))

((= n 1) '( ; sig = 1
( 1.296131424196177  0.506786305427196  0.315129518355791  0.569049818628484)
( 0.624558126821597  0.782146641374009 -0.227993111082042  0.852255024312201)
( 0.226177911154779 -0.539984274165291  0.407592072465429  0.770351954376606)
(-0.4885973470206   -0.5945552744784   -0.938719583848988 -0.063536886954438)))

((= n 2) '( ; sig = 3
( 1.058382738454450  1.080428865520375  1.127465422599250 -0.127758660571711)
(-1.128402682750040  3.919407819888167  2.335041474200306 -3.191023595463133)
( 1.175606824480543 -2.513505943598499 -0.990243419935290  2.778341502325632)
( 0.106842078464432 -3.035024227834949 -2.596731586950658  1.865414795322595)))

((= n 3) '( ; sig = 7
( 0.699380138288892  0.732528047123960  0.198094511473926 -0.254894788358502)
(-2.052327594654551  3.296452488081635 -0.113798649237099 -3.753877687742145)
(-1.455142399174346  1.954891284795403  1.098239425929325 -2.478945173639279)
( 2.412181696201262 -3.771577426140406 -0.508253287947906  4.615380615027338)))))

(define (linear? f) (let ((c (Cr))(d (Cr))(s (Kr))) ; for C -> K
(and (= (* s (f c))(f (sm s c)))
(= (f (C+ c d))(+ (f c)(f d))))))
; (map linear? (list rp Q)) => (#t #f)
(define (bilinear? f) (let ((y (Cr))) (and ; for C × C -> K
(linear? (lambda (x) (f x y)))
(linear? (lambda (x) (f y x))))))
; (map bilinear? (list sp ip)) => (#t #t)

(let ((a (Cr))) (-(sp a a) (-(mag2 (even a)) (mag2 (odd a))))) ; => 0 NOT!
; (map Q basis) => (1 -1 -1 -1) when sig => (- + + +)
(let ((v (Vr))(w (Vr))) (- (Q v) (Q (turn v w)))) ; Does turn preserve quadratic form? (yes)
(let* ((z (Vr))(nz (nc om z))) (list z (mag2 z) nz (mag2 nz)))
; (let ((z (Vr))) (= (mag2 z) (mag2 (nc om z)))) => #t
```