Skip to content

Commit ea1f59d

Browse files
committed
implement primal coordinate vector, work to lazify /\ operators
1 parent 64e2132 commit ea1f59d

File tree

7 files changed

+552
-312
lines changed

7 files changed

+552
-312
lines changed

aplesque/aplesque.lisp

+2-1
Original file line numberDiff line numberDiff line change
@@ -2141,7 +2141,8 @@
21412141
(oscalar (if (zerop (rank omega)) (disclose omega)))
21422142
(osize (size omega)) (adims (dims alpha)) (odims (dims omega))
21432143
(output (make-array (append adims odims))))
2144-
(xdotimes output (i (size output) :synchronous-if (not threaded))
2144+
;; (xdotimes output (i (size output) :synchronous-if (not threaded))
2145+
(dotimes (i (size output))
21452146
(setf (row-major-aref output i)
21462147
(funcall function (or oscalar (disclose (row-major-aref omega (mod i osize))))
21472148
(or ascalar (disclose (row-major-aref alpha (floor i osize)))))))

functions.lisp

+1-1
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@
326326
(= 1 (length index))))
327327
(make-instance 'vapri-integer-progression :number index :origin index-origin)
328328
(make-instance 'vapri-coordinate-identity :shape (coerce index 'list)
329-
:origin index-origin))))
329+
:index-origin index-origin))))
330330

331331
(defun inverse-count-to (vector index-origin)
332332
"The [⍳ index] function inverted; it returns the length of a sequential integer array starting from the index origin or else throws an error."

grammar.lisp

-17
Original file line numberDiff line numberDiff line change
@@ -1030,23 +1030,6 @@
10301030
operator (or rfn-wrap right-value)
10311031
lfn-wrap left-value)))))))))
10321032

1033-
;; (defun reverse-asel-function (form &optional (wrap #'identity))
1034-
;; (print (list :ff form))
1035-
;; (if (and (listp form) (eql 'a-call (first form)))
1036-
;; ;; TODO: change the membership check to check metadata from spec
1037-
;; (destructuring-bind (function-form arg1 &rest arg2-rest) (rest form)
1038-
;; (if (not (and (listp (second form))
1039-
;; (member (cadadr form) '(⊃ ⌷)))) ; ↑ ↓ / \\
1040-
;; (reverse-asel-function arg1 (lambda (item)
1041-
;; (funcall wrap (append (list 'a-call function-form item)
1042-
;; arg2-rest))))
1043-
;; (reverse-asel-function arg1 (lambda (item)
1044-
;; (append (list 'a-call function-form
1045-
;; (funcall wrap item))
1046-
;; arg2-rest)))))
1047-
;; ;; TODO: add argument-isolating form here for full lazy mode
1048-
;; (funcall wrap (list 'identity form))))
1049-
10501033
(defun compose-value-assignment (symbol value &key function space params)
10511034
"Compose a value assignment like v←1 2 3."
10521035
(cond ((eql 'to-output symbol)

spec.lisp

+23-12
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,9 @@
613613
(ambivalent (λω (make-instance 'vader-pare :base omega :index-origin index-origin
614614
:axis (first axes)))
615615
(λωα (make-instance
616-
'vader-catenate :base (vector alpha omega) :index-origin index-origin
616+
'vader-catenate :base (if (eq omega :arg-vector)
617+
alpha (vector alpha omega))
618+
:index-origin index-origin
617619
:axis (or (first axes) :last))))
618620
(meta (primary :axes axes :implicit-args (index-origin) :virtual-support t)
619621
(dyadic :on-axis :last))
@@ -682,7 +684,9 @@
682684
(ambivalent (λω (make-instance 'vader-pare :base omega :index-origin index-origin
683685
:axis :tabulate))
684686
(λωα (make-instance
685-
'vader-catenate :base (vector alpha omega) :index-origin index-origin
687+
'vader-catenate :base (if (eq omega :arg-vector)
688+
alpha (vector alpha omega))
689+
:index-origin index-origin
686690
:axis (or (first axes) index-origin))))
687691
(meta (primary :axes axes :implicit-args (index-origin) :virtual-support t)
688692
(dyadic :on-axis :first))
@@ -939,7 +943,8 @@
939943
(is "4 (⊂1 3)⊃(5×⍳6)×6⍴⊂3 4⍴⍳12" 60)))
940944
(∩ (has :title "Intersection")
941945
(dyadic ;; #'array-intersection
942-
(λωα (make-instance 'vader-intersection :base (vector alpha omega))))
946+
(λωα (make-instance 'vader-intersection :base (if (eq omega :arg-vector)
947+
alpha (vector alpha omega)))))
943948
(meta (primary :virtual-support t))
944949
(tests (is "2∩⍳4" #(2))
945950
(is "4 5 6∩4" #(4))
@@ -954,7 +959,7 @@
954959
;; #'array-union
955960
(λωα (make-instance 'vader-union :base (vector alpha omega))))
956961
(meta (primary :virtual-support t)
957-
(monadic) (dyadic :id #'vector))
962+
(monadic) (dyadic :id #()))
958963
(tests (is "∪3" #(3))
959964
(is "∪1 2 3 4 5 1 2 8 9 10 11 7 8 11 12" #(1 2 3 4 5 8 9 10 11 7 12))
960965
(is "∪'MISSISSIPPI'" "MISP")
@@ -1328,8 +1333,12 @@
13281333
(:demo-profile :title "Lateral Operator Demos"
13291334
:description "Lateral operators take a single operand function to their left, hence the name 'lateral.' The combination of operator and function yields another function which may be applied to one or two arguments depending on the operator."))
13301335
(/ (has :title "Reduce")
1331-
(lateral (lambda (operand) (values `(operate-reducing ,operand index-origin t)
1332-
'(:axis))))
1336+
(lateral (lambda (operand)
1337+
;; (values `(operate-reducing ,operand index-origin t)
1338+
;; '(:axis))
1339+
(values `(op-compose 'vacomp-reduce :left (sub-lex ,operand)
1340+
:index-origin index-origin)
1341+
'(:axis))))
13331342
(tests (is "+/1 2 3 4 5" 15)
13341343
(is "⊢/⍳5" 5)
13351344
(is "×/5" 5)
@@ -1346,7 +1355,7 @@
13461355
(is "</⍬" 0)
13471356
(is "≤/⍬" 1)
13481357
(is "⊤/⍬" 0)
1349-
(is "∪/⍬" #())
1358+
(is "∪/⍬" #0A#())
13501359
(is "f←+ ⋄ f/⍬" 0)
13511360
(is "g←÷ ⋄ g/⍬" 1)
13521361
(is "⍴×/0 0 0⍴0" #*00)
@@ -1385,7 +1394,7 @@
13851394
(lateral (lambda (operand)
13861395
;; (april (with (:space array-lib-space) (:unrendere)) "↓disp 1 0 1 /sam⊢{⊂'---'}¨ vex")
13871396
;; `(operate-each ,operand) ; "bla←{ ⍺[0] } ⋄ {⎕io←0 ⋄ {⍵∘bla¨⊂0 1} ⎕←⍵} 3 4"
1388-
`(op-compose 'vacomp-each (sub-lex ,operand))
1397+
`(op-compose 'vacomp-each :left (sub-lex ,operand))
13891398
))
13901399
(tests (is "⍳¨1 2 3" #(#(1) #(1 2) #(1 2 3)))
13911400
(is "⊃¨↓⍳5" 1)
@@ -2591,13 +2600,15 @@ fun 3")) 8))
25912600

25922601
(format t "λ Compact operator-composed function calls.~%")
25932602

2594-
(is (print-and-run (april-c "{⍵⍵ ⍺⍺/⍵}" #'+ #'- #(1 2 3 4 5)))
2595-
-15 :test #'=)
2603+
;; TODO: need lazy wrapping for the passed functions
2604+
;; (is (print-and-run (april-c "{⍵⍵ ⍺⍺/⍵}" #'+ #'- #(1 2 3 4 5)))
2605+
;; -15 :test #'=)
25962606

25972607
(format t "~%")
25982608

2599-
(is (print-and-run (april-c "{⍵⍵ ⍺ ⍺⍺/⍵}" #'+ (scalar-function -) #(1 2 3 4 5) 3))
2600-
#(-6 -9 -12) :test #'equalp))
2609+
;; (is (print-and-run (april-c "{⍵⍵ ⍺ ⍺⍺/⍵}" #'+ (scalar-function -) #(1 2 3 4 5) 3))
2610+
;; #(-6 -9 -12) :test #'equalp)
2611+
)
26012612
)))
26022613

26032614
;; create the common workspace and the space for unit tests

utilities.lisp

+59-21
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,12 @@
108108
,form (lambda (&rest ,args)
109109
(let ((,this-meta (apply ,form (cons :get-metadata
110110
(when (second ,args) (list nil))))))
111-
;; pass the environment variables if this is a user-defined function
112-
(apply ,form (append ,args (when (not (second ,args)) (list nil))
111+
;; pass the environment variables if this is a user-defined function;
112+
;; remember not to add the nil argument if an internal
113+
;; variable state is being set
114+
(apply ,form (append ,args (when (and (not (second ,args))
115+
(getf ,this-meta :lexical-reference))
116+
(list nil))
113117
(when (not (getf ,this-meta :lexical-reference))
114118
(list (list :index-origin index-origin)))))))))))
115119

@@ -242,6 +246,7 @@
242246
,env))
243247
,@(loop :for var :in params :when (not (eql '&optional var))
244248
:collect `(setq ,var (render-varrays ,var)))
249+
;; (print (list :par ,@(remove '&optional (append params (list env 'abc)))))
245250
(if (eq :get-metadata ,(first params))
246251
,(cons 'list meta)
247252
(let ,(if space
@@ -1081,9 +1086,7 @@
10811086
(cddr function)))))))
10821087
`(let ((,arg-list (list ,@arguments ))) ;,@(if axes-present (list (third function))))))
10831088
(apply ,@(if is-scalar (list '#'apply-scalar))
1084-
,(if t ; (not axes-present)
1085-
function (butlast function 1))
1086-
,arg-list))))))
1089+
,function ,arg-list))))))
10871090

10881091
(defun join-fns (form &optional wrap)
10891092
"Compose multiple successive scalar functions into a larger scalar function. Used to expand (a-call)."
@@ -1273,23 +1276,56 @@ It remains here as a standard against which to compare methods for composing APL
12731276
(>= 2 (length function)))
12741277
function (list (first function) (second function))))
12751278
(axes (and (listp function) (eql 'apl-fn (first function))
1276-
(third function))))
1279+
(third function)))
1280+
(fn-quoted (if (not (symbolp function)) function (list 'function function))))
12771281
`(lambda (&rest ,args)
12781282
(let ((,ax-sym (third ,args)))
12791283
(declare (ignorable ,ax-sym))
1280-
(if (eq :get-metadata (first ,args))
1281-
,(append '(list :scalar t) meta)
1282-
,(if is-virtual
1283-
`(make-instance 'vader-operate
1284-
:base (coerce (if (not ,ax-sym)
1285-
,args (butlast ,args))
1286-
'vector)
1287-
:function ,(if (not (symbolp function)) function `(function ,function))
1288-
:index-origin 0 :axis ,ax-sym :params (list ,@meta))
1289-
`(apply-scalar ,(if (not (symbolp function)) function `(function ,function))
1290-
(first ,args) (second ,args)
1291-
;; ,@(if axes (list axes))
1292-
,ax-sym)))))))
1284+
;; (print (list :ff ',function))
1285+
(case (first ,args)
1286+
(:get-metadata ,(append '(list :scalar t) meta))
1287+
(:arg-vector (make-instance 'vader-operate
1288+
:base (second ,args) :index-origin 0 :params (list ,@meta)
1289+
:axis ,ax-sym :function ,fn-quoted))
1290+
(:call-scalar (apply ,fn-quoted (rest ,args)))
1291+
(t ,(if is-virtual
1292+
`(make-instance 'vader-operate
1293+
;; :base (coerce (if (not ,ax-sym) ,args (butlast ,args))
1294+
;; 'vector)
1295+
;; :base (reverse (if (not ,ax-sym) ,args (butlast ,args)))
1296+
:base (if (not ,ax-sym) ,args (butlast ,args))
1297+
:function ,fn-quoted :index-origin 0 :axis ,ax-sym
1298+
:params (list ,@meta))
1299+
`(apply-scalar ,fn-quoted (first ,args) (second ,args)
1300+
;; ,@(if axes (list axes))
1301+
,ax-sym))))))))
1302+
1303+
;; (defmacro scalar-function (function &rest meta)
1304+
;; "Wrap a scalar function. This is a passthrough macro used by the scalar composition system in (a-call)."
1305+
;; (let ((args (gensym)) (ax-sym (gensym))
1306+
;; (is-virtual (getf meta :va))
1307+
;; (function (if (or (not (listp function))
1308+
;; (not (eql 'apl-fn (first function)))
1309+
;; (>= 2 (length function)))
1310+
;; function (list (first function) (second function))))
1311+
;; (axes (and (listp function) (eql 'apl-fn (first function))
1312+
;; (third function))))
1313+
;; `(lambda (&rest ,args)
1314+
;; (let ((,ax-sym (third ,args)))
1315+
;; (declare (ignorable ,ax-sym))
1316+
;; (if (eq :get-metadata (first ,args))
1317+
;; ,(append '(list :scalar t) meta)
1318+
;; ,(if is-virtual
1319+
;; `(make-instance 'vader-operate
1320+
;; :base (coerce (if (not ,ax-sym)
1321+
;; ,args (butlast ,args))
1322+
;; 'vector)
1323+
;; :function ,(if (not (symbolp function)) function `(function ,function))
1324+
;; :index-origin 0 :axis ,ax-sym :params (list ,@meta))
1325+
;; `(apply-scalar ,(if (not (symbolp function)) function `(function ,function))
1326+
;; (first ,args) (second ,args)
1327+
;; ;; ,@(if axes (list axes))
1328+
;; ,ax-sym)))))))
12931329

12941330
(defun validate-arg-unitary (value)
12951331
"Verify that a form like (vector 5) represents a unitary value."
@@ -2051,6 +2087,8 @@ It remains here as a standard against which to compare methods for composing APL
20512087
(defmacro amb-ref (fn-monadic fn-dyadic &optional axes is-virtual)
20522088
"Generate a function aliasing a lexical function which may be monadic or dyadic; an ambivalent reference."
20532089
(let ((args (gensym)) (iargs (gensym)) (reduced-args (gensym)) (this-fn (gensym)) (a (gensym))
2090+
(m-scalar (when (eq 'scalar-function (first fn-monadic)) '(:scalar t)))
2091+
(d-scalar (when (eq 'scalar-function (first fn-dyadic)) '(:scalar t)))
20542092
(m-meta (if (member (first fn-monadic) '(fn-meta scalar-function))
20552093
(cddr fn-monadic)))
20562094
(d-meta (if (member (first fn-dyadic) '(fn-meta scalar-function))
@@ -2069,8 +2107,8 @@ It remains here as a standard against which to compare methods for composing APL
20692107
(setq ,axes (second ,args)
20702108
,args (cddr ,args)))))
20712109
(if (eq :get-metadata (first ,args))
2072-
(if (= 1 (length ,args)) ,(if m-meta (cons 'list m-meta))
2073-
,(if d-meta (cons 'list d-meta)))
2110+
(if (= 1 (length ,args)) ,(if m-meta (cons 'list (append m-scalar m-meta)))
2111+
,(if d-meta (cons 'list (append d-scalar d-meta))))
20742112
(if (= 2 (length ,args))
20752113
(if (null (second ,args))
20762114
(a-call ,fn-monadic (first ,args))

varray/package.lisp

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#:vader-encode #:vader-decode #:vader-identity
1616

1717
#:vader-composing #:op-compose
18-
#:vacomp-each
18+
#:vacomp-reduce #:vacomp-each
1919
)
2020
(:shadowing-import-from #:aplesque #:enclose #:disclose #:disclose-unitary #:get-dimensional-factors
2121
#:assign-element-type #:type-in-common #:apl-array-prototype

0 commit comments

Comments
 (0)