Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error Node And Maybe Compilation Wrapper #129

Merged
merged 5 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions src/lambda/lambda.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ to the codomain."
((typep f 'lamb) (mcadr (ttype rec)))
((typep f 'app) (hom-cod ctx (fun f)))
((typep f 'index) (mcadr (ttype rec)))
((typep f 'err) (mcadr (ttype f)))
(t (error "not a valid STLC exponential term")))))

(-> index-check (fixnum list) cat-obj)
Expand Down Expand Up @@ -162,6 +163,7 @@ the context on the left as well. For more info check [LAMB][class]"))
:ttype (hom-cod ctx fun)))
((index pos) (index pos
:ttype (index-check pos ctx)))
((err ttype) (err ttype))
((case-on on ltm rtm)
(let* ((ann-on (ann-term1 ctx on))
(type-of-on (ttype ann-on))
Expand Down Expand Up @@ -227,7 +229,8 @@ occurences - re-annotates the term and its subterms with actual
(mapcar #'ann-term2 term)
:ttype (fun-to-hom (ttype tterm))))
((index pos) (index pos
:ttype (fun-to-hom (ttype tterm))))))
:ttype (fun-to-hom (ttype tterm))))
((err ttype) (err (fun-to-hom ttype)))))

(defun annotated-term (ctx term)
"Given a context consisting of a list of [SUBSTOBJ][GEB.SPEC:SUBSTOBJ]
Expand Down Expand Up @@ -307,7 +310,25 @@ nil"))
(and (check fun)
(check (reduce #'pair term))))
(index t)
(unit t))))
(unit t)
(err t))))
(let ((term (ignore-errors
(ann-term1 ctx tterm))))
(and term (check term)))))

(defun errorp (tterm)
"Evaluates to true iff the term has an error subterm."
(cond ((or (typep tterm 'index)
(typep tterm 'unit)) nil)
((typep tterm 'err) t)
((typep tterm 'case-on) (or (errorp (on tterm))
(errorp (rtm tterm))
(errorp (ltm tterm))))
((typep tterm 'pair) (or (errorp (ltm tterm))
(errorp (rtm tterm))))
((typep tterm 'app) (or (errorp (fun tterm))
(some #'identity
(mapcar
(lambda (x) (errorp x))
(term tterm)))))
(t (errorp (term tterm)))))
1 change: 1 addition & 0 deletions src/lambda/package.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
(well-defp pax:generic-function)
(fun-type pax:class)
(fun-type pax:function)
(errorp pax:function)

(mcar (pax:method () (fun-type)))
(mcadr (pax:method () (fun-type)))
Expand Down
212 changes: 200 additions & 12 deletions src/lambda/trans.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,189 @@ calling me"
(defmethod empty ((class (eql (find-class 'list)))) nil)

(defmethod to-cat (context (tterm <stlc>))
"Compiles a checked term in said context to a Geb morphism. If the term has
an instance of an erorr term, wraps it in a Maybe monad, otherwise, compiles
according to the term model interpretation of STLC"
(if (errorp tterm)
(to-cat-err context tterm)
(to-cat-cor context tterm)))

(defun maybe-comp (ob)
"Takes a [SUBSTOBJ][GEB.SPEC:SUBSTOBJ] with possible fun-type instances
and removes them"
(fun-to-hom (maybe ob)))

(defun maybe-rest (ob)
"Takes a Geb object wrapped in Maybe and gives out the part without the
error node"
(mcadr (maybe-comp ob)))

(defmethod to-cat-err (context (tterm <stlc>))
"Compiles a checked term with an error term in an appropriate context into the
morphism of the GEB category using a Maybe monad wrapper, that is, given a
context G and a term t of type A produces a morphism with domain
(stlc-ctx-maybe context) and codomain (maybe A).

Terms come from [STLC][type] with occurences of [SO-HOM-OBJ][GEB.MAIN:SO-HOM-OBJ]
replaced by [FUN-TYPE][class] and should come without the slow of
[TTYPE][generic-function] accessor filled for any of the subterms. Context should
be a list of [SUBSTOBJ][GEB.SPEC:SUBSTOBJ] with the caveat that instead of
[SO-HOM-OBJ][GEB.MAIN:SO-HOM-OBJ] we ought to use [FUN-TYPE][class], a stand-in
for the internal hom object with explicit accessors to the domain and the
codomain. Once again, note that it is important for the context and term to be
giving as per above description. While not always, not doing so result in an
error upon evaluation. As an example of a valid entry we have

```lisp
(to-cat-err (list so1 (fun-type so1 so1)) (app (index 1) (list (error so1))))
```

while

```lisp
(to-cat-err (list so1 (so-hom-obj so1 so1)) (app (index 1) (list (error so1))))
```

produces an error. Error of such kind mind pop up both on the level of evaluating
[WELL-DEFP][generic-function] and [ANN-TERM1][generic-function].

Moreover, note that for terms whose typing needs addition of new context
we append contexts on the left rather than on the right contra usual type
theoretic notation for the convenience of computation. That means, e.g. that
asking for a type of a lambda term as below produces:

```lisp
LAMBDA> (ttype (term (ann-term1 nil (lamb (list so1 so0) (index 0)))))
s-1
```

as we count indeces from the left of the context while appending new types to
the context on the left as well. For more info check [LAMB][class]

Note that the Maybe wrapper also applies to the context elements due to
functoriality concerns. Hence if one wanted to check the whether the term
(case-on (index 0) (err so1) (unit)) with a bool in contexts fails on the
left entry, one would need to evaluate

```lisp
LAMBDA> (gapply (to-cat (list (coprod so1 so1))
(case-on (index 0)
(err so1)
(unit)))
(list (geb:right (geb:left (geb:right so1))) so1))
(left s-1)
```

and hence get an error part of the wrapper. While evaluating the right branch
will be done by:

```lisp
LAMBDA> (gapply (to-cat (list (coprod so1 so1))
(case-on (index 0)
(err so1)
(unit)))
(list (geb:right (geb:right (geb:right so1))) so1))
(right s-1)
```

This follows from the fact that bool arapped in maybe is 1 + (bool + bool)"
(labels ((rec (context tterm)
(match-of stlc tterm
((absurd tcod term)
(comp (mcase (->left so1 (maybe-rest tcod))
(init (maybe-comp tcod)))
(rec context term)))
(unit
(comp (->right so1 so1)
(terminal (stlc-ctx-maybe context))))
((left rty term)
(comp (->right so1 (maybe-rest (ttype tterm)))
(comp (->left (maybe-comp (ttype term))
(maybe-comp rty))
(rec context term))))
((right lty term)
(comp (->right so1 (maybe-rest (ttype tterm)))
(comp (->right (maybe-comp lty)
(maybe-comp (ttype term)))
(rec context term))))
((case-on on ltm rtm)
(let ((mcartoon (mcar (ttype on)))
(mcadrtoon (mcadr (ttype on)))
(ctx (stlc-ctx-maybe context)))
(comp (mcase (comp (->left so1 (maybe-rest (ttype tterm)))
(terminal (prod ctx so1)))
(comp (mcase (commutes-left
(rec
(cons mcartoon
context)
ltm))
(commutes-left
(rec
(cons mcadrtoon
context)
rtm)))
(distribute ctx
(maybe-comp mcartoon)
(maybe-comp mcadrtoon))))
(comp (distribute ctx
so1
(maybe-rest (coprod mcartoon
mcadrtoon)))
(geb:pair ctx (rec context on))))))
((pair ltm rtm)
(let ((lty (ttype ltm))
(rty (ttype rtm)))
(comp (->right so1 (prod (maybe-comp lty)
(maybe-comp rty)))
(geb:pair (rec context ltm)
(rec context rtm)))))
((fst term)
(let ((mcarttot (mcar (ttype term))))
(comp (mcase (->left so1 (maybe-rest mcarttot))
(<-left (maybe-comp mcarttot)
(maybe (mcadr (ttype term)))))
(rec context term))))
((snd term)
(let ((mcadrttot (mcadr (ttype term))))
(comp (mcase (->left so1 (maybe-rest mcadrttot))
(<-right (maybe-comp (mcar (ttype term)))
(maybe-comp mcadrttot)))
(rec context term))))
((lamb tdom term)
(comp (->right so1 (maybe-rest (fun-to-hom (ttype tterm))))
(apply-n (length tdom)
#'(lambda (x) (curry (commutes-left x)))
(rec (append
(mapcar #'maybe-comp tdom)
context) term))))
((app fun term)
(let ((tofun (ttype fun)))
(comp
(mcase (->left so1 (maybe-rest tofun))
(commutes-left
(so-eval (maybe-comp (mcar tofun))
(maybe-comp (mcadr tofun)))))
(comp (distribute (reduce #'prod
(mapcar #'maybe-comp term)
:from-end t)
so1
(maybe-rest tofun))
(geb:pair (reduce #'geb:pair
(mapcar #'(lambda (x) (rec context x)) term)
:from-end t)
(rec context
fun))))))
((index pos)
(stlc-ctx-proj (mapcar #'maybe context) pos))
((err ttype)
(comp (->left so1 (maybe-comp ttype))
(terminal (stlc-ctx-maybe context)))))))
(if (not (well-defp context tterm))
(error "not a well-defined ~A in said ~A" tterm context)
(rec context (ann-term1 context tterm)))))

Comment on lines +136 to +230
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most painful kind of copy and paste.

Let us remove this with a better strategy later, or find a way to abstract it if it has to live here long term


(defmethod to-cat-cor (context (tterm <stlc>))
"Compiles a checked term in an appropriate context into the
morphism of the GEB category. In detail, it takes a context and a term with
following restrictions: Terms come from [STLC][type] with occurences of
Expand All @@ -61,13 +244,13 @@ always, not doing so result in an error upon evaluation. As an example of a
valid entry we have

```lisp
(to-cat (list so1 (fun-type so1 so1)) (app (index 1) (list (index 0))))
(to-cat-cor (list so1 (fun-type so1 so1)) (app (index 1) (list (index 0))))
```

while

```lisp
(to-cat (list so1 (so-hom-obj so1 so1)) (app (index 1) (list (index 0))))
(to-cat-cor (list so1 (so-hom-obj so1 so1)) (app (index 1) (list (index 0))))
```

produces an error. Error of such kind mind pop up both on the level of evaluating
Expand All @@ -87,7 +270,7 @@ as we count indeces from the left of the context while appending new types to
the context on the left as well. For more info check [LAMB][class]

Finally, note that the compilation uncurries the final morphism. That is,
if the type of the term is an exponential object, [TO-CAT] uncurries the
if the type of the term is an exponential object, [TO-CAT-COR] uncurries the
morphism in the Geb category instead producing a morphism into the domain
of the exponential from a corresponding product. If the exponential is
iterated, so is the uncurrying."
Expand All @@ -98,14 +281,12 @@ iterated, so is the uncurrying."
(rec context term)))
(unit
(terminal (stlc-ctx-to-mu context)))
((left term)
(let ((tott (ttype tterm)))
(comp (->left (mcar tott) (mcadr tott))
(rec context term))))
((right term)
(let ((tott (ttype tterm)))
(comp (->right (mcar tott) (mcadr tott))
(rec context term))))
((left rty term)
(comp (->left (ttype term) rty)
(rec context term)))
((right lty term)
(comp (->right lty (ttype term))
(rec context term)))
Comment on lines -95 to +289
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should do these kinds of changes in a different topic, if they are unrelated to your changes.

((case-on on ltm rtm)
(let ((mcartoon (mcar (ttype on)))
(mcadrtoon (mcadr (ttype on)))
Expand Down Expand Up @@ -141,7 +322,9 @@ iterated, so is the uncurrying."
(mapcar #'(lambda (x) (rec context x)) term)
:from-end t)))))
((index pos)
(stlc-ctx-proj context pos)))))
(stlc-ctx-proj context pos))
(err
(error "Not meant for the compiler")))))
(cond ((not (well-defp context tterm))
(error "not a well-defined ~A in said ~A" tterm context))
((typep (type-of-term-w-fun context tterm) 'fun-type)
Expand Down Expand Up @@ -218,6 +401,11 @@ LAMBDA> (stlc-ctx-to-mu (list so1 (fun-to-hom (fun-type geb-bool:bool geb-bool:b
```"
(mvfoldr #'prod (mapcar #'fun-to-hom context) so1))

(defun stlc-ctx-maybe (context)
"Takes a context seen as product of appropriate [SUBSTOBJ][GEB.SPEC:SUBSTOBJ]
and iteratively applies Maybe to its elements."
(mvfoldr #'prod (mapcar (lambda (x) (maybe-comp x)) context) so1))

(-> so-hom (substobj substobj) (or t substobj))
(defun so-hom (dom cod)
"Computes the hom-object of two [SUBSTMORPH]s"
Expand Down
1 change: 1 addition & 0 deletions src/specs/lambda-printer.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
(easy-printer lamb)
(easy-printer app)
(easy-printer index)
(easy-printer err)
22 changes: 20 additions & 2 deletions src/specs/lambda.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ unit types as well as coproduct, product, and function types."))
"Type of untyped terms of [STLC][type]. Each class of a term has a slot for a type,
which can be filled by auxillary functions or by user. Types are
represented as [SUBSTOBJ][GEB.SPEC:SUBSTOBJ]."
'(or absurd unit left right case-on pair fst snd lamb app index))

'(or absurd unit left right case-on pair fst snd lamb app index err))

;; New defgenerics

Expand Down Expand Up @@ -537,4 +536,23 @@ type-theoretic notation."))
(values
(make-instance 'index :pos pos :ttype ttype)))

(defclass err (<stlc>)
((ttype :initarg :ttype
:initform nil
:accessor ttype
:documentation ""))
(:documentation
"An error term of a type supplied by the user. The formal grammar of
[ERR][class] is
```lisp
(err ttype)
```
The intended semantics are as follows: [ERR][class] represents an error node
currently having no particular feedback but with functionality to be of an
arbitrary type. Note that this is the only STLC term class which does not
have [TTYPE][generic-function] a possibly empty accessor."))

(-> err (cat-obj) err)
(defun err (ttype)
(values
(make-instance 'err :ttype ttype)))
5 changes: 5 additions & 0 deletions src/specs/package.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ constructors"
(lamb pax:class)
(app pax:class)
(index pax:class)
(err pax:class)

(absurd pax:function)
(unit pax:function)
Expand All @@ -170,6 +171,7 @@ constructors"
(lamb pax:function)
(app pax:function)
(index pax:function)
(err pax:function)

"Accessors of [ABSURD][class]"

Expand Down Expand Up @@ -223,6 +225,9 @@ constructors"
(pos (pax:method () (index)))
(ttype (pax:method () (index)))

"Accessors of [ERR][class]"
(ttype (pax:method () (err)))

(tcod pax:generic-function)
(tdom pax:generic-function)
(term pax:generic-function)
Expand Down
Loading