Generalizing Lisp functions - mapping

For rapid prototyping purposes, I would like to start building a library of generalized versions of some basic functions provided in Common Lisp, rather than only collect (or import) special purpose functions for the task at hand. For example, the map function is moderately generalized to operate on sequences of any kind, but does not handle adjustable vectors. Writing the special purpose extension below seems sufficient for present use, but remains limited:
(defun map-adjustable-vector (function adjustable-vector)
"Provides mapping across items in an adjustable vector."
(let ((new-adj-vec
(make-array (array-total-size adjustable-vector)
:element-type (array-element-type adjustable-vector)
:adjustable t
:fill-pointer (fill-pointer adjustable-vector))))
(dotimes (i (array-total-size adjustable-vector))
(setf (aref new-adj-vec i) (funcall function (aref adjustable-vector i))))
new-adj-vec))
What I would like to see is how to go about writing a function like this that additionally takes an output type spec (including a new 'adjustable-vector type) and allows multiple kinds of lists and vectors as input--in other words, patterned after map.
More broadly, it would be useful to understand if there are basic principles or ideas relevant to writing such generalized functions. For example, would generic methods specializing on the output type specs be a viable approach for the above function? Or, perhaps, could leveraging map itself figure in the generalization, as coredump illustrated in a previous post at Mapping into a tree of nested sequences? I don't know if there are any limits to generalization (excepting a certain inefficiency), but I would like to see how far it can go.

In this case, map can be thought to use make-sequence to create the resulting sequence.
However, your question is too broad, and any answer is basically an opinion. You can make whatever you want, but essentially, the most direct approach is to extend the sequence type argument to include vectors with fill pointers and/or that are adjustable:
;;; For use by the following deftype only
(defun my-vector-typep (obj &key (adjustable '*) (fill-pointer '*))
(and (or (eql adjustable '*)
;; (xor adjustable (adjustable-array-p obj))
(if adjustable
(adjustable-array-p obj)
(not (adjustable-array-p obj))))
(or (eql fill-pointer '*)
(if (null fill-pointer)
(not (array-has-fill-pointer-p obj))
(and (array-has-fill-pointer-p obj)
(or (eql fill-pointer t)
(eql fill-pointer (fill-pointer obj))))))))
;;; A type whose purpose is to describe vectors
;;; with fill pointers and/or that are adjustable.
;;;
;;; element-type and size are the same as in the type vector
;;; adjustable is a generalized boolean, or *
;;; fill-pointer is a valid fill pointer, or t or nil, or *
(deftype my-vector (&key element-type size adjustable fill-pointer)
(if (and (eql adjustable '*) (eql fill-pointer '*))
`(vector element-type size)
;; TODO: memoize combinations of adjustable = true/false/* and fill-pointer = t/nil/*
(let ((function-name (gensym (symbol-name 'my-vector-p))))
(setf (symbol-function function-name)
#'(lambda (obj)
(my-vector-p obj :adjustable adjustable :fill-pointer fill-pointer)))
`(and (vector ,element-type ,size)
(satisfies ,function-name)))))
(defun my-make-sequence (resulting-sequence-type size &key initial-element)
(when (eql resulting-sequence-type 'my-vector)
(setf resulting-sequence-type '(my-vector)))
(if (and (consp resulting-sequence-type)
(eql (first resulting-sequence-type) 'my-vector))
(destructuring-bind (&key (element-type '*) (type-size '* :size) (adjustable '*) (fill-pointer '*))
(rest resulting-sequence-type)
(assert (or (eql type-size '*) (<= size type-size)))
(make-array (if (eql type-size '*) size type-size)
:element-type (if (eql element-type '*) t element-type)
:initial-element initial-element
:adjustable (if (eql adjustable '*) nil adjustable)
:fill-pointer (if (eql fill-pointer '*) nil fill-pointer)))
(make-sequence resulting-sequence-type size
:initial-element initial-element)))
;; > (my-make-sequence '(my-vector :adjustable t) 10)
(defun my-map (resulting-sequence-type function &rest sequences)
(apply #'map-into
(my-make-sequence resulting-sequence-type
(if (null sequences)
0
(reduce #'min (rest sequences)
:key #'length
:initial-value (length (first sequence))))
function
sequences)))
;; > (my-map '(my-vector :adjustable t) #'+ '(1 2 3) '(3 2 1))
There are many other choices, like simply providing the target sequence explicitly (map-into), providing a sequence factory function with specific arguments or using a specializable generic function (if possible), using a wrapper object that decides how to store elements internally (e.g. if it is sorted, perhaps use a tree; if it has few elements, perhaps use conses) and that can return any kind of sequence.
Really, this is such an open-ended question, it depends mostly on your needs and/or imagination.

Related

forall usage in SMT

How does forall statement work in SMT? I could not find information about usage. Can you please simply explain this? There is an example from
https://rise4fun.com/Z3/Po5.
(declare-fun f (Int) Int)
(declare-fun g (Int) Int)
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(assert (forall ((x Int))
(! (= (f (g x)) x)
:pattern ((g x)))))
(assert (= (g a) c))
(assert (= (g b) c))
(assert (not (= a b)))
(check-sat)
For general information on quantifiers (and everything else SMTLib) see the official SMTLib document:
http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.6-r2017-07-18.pdf
Quoting from Section 3.6.1:
Exists and forall quantifiers. These binders correspond to the usual
universal and existential quantifiers of first-order logic, except
that each variable they quantify is also associated with a sort. Both
binders have a non-empty list of variables, which abbreviates a
sequential nesting of quantifiers. Specifically, a formula of the form
(forall ((x1 σ1) (x2 σ2) · · · (xn σn)) ϕ) (3.1) has the same
semantics as the formula (forall ((x1 σ1)) (forall ((x2 σ2)) (· · ·
(forall ((xn σn)) ϕ) · · · ) (3.2) Note that the variables in the list
((x1 σ1) (x2 σ2) · · · (xn σn)) of (3.1) are not required to be
pairwise disjoint. However, because of the nested quantifier
semantics, earlier occurrences of same variable in the list are
shadowed by the last occurrence—making those earlier occurrences
useless. The same argument applies to the exists binder.
If you have a quantified assertion, that means the solver has to find a satisfying instance that makes that formula true. For a forall quantifier, this means it has to find a model that the assertion is true for all assignments to the quantified variables of the relevant sorts. And likewise, for exists the model needs to be able to exhibit a particular value satisfying the assertion.
Top-level exists quantifiers are usually left-out in SMTLib: By skolemization, declaring a top-level variable fills that need, and also has the advantage of showing up automatically in models. (That is, any top-level declared variable is automatically existentially quantified.)
Using forall will typically make the logic semi-decidable. So, you're likely to get unknown as an answer if you use quantifiers, unless some heuristic can find a satisfying assignment. Similarly, while the syntax allows for nested quantifiers, most solvers will have very hard time dealing with them. Patterns can help, but they remain hard-to-use to this day. To sum up: If you use quantifiers, then SMT solvers are no longer decision-procedures: They may or may not terminate.
If you are using the Python interface for z3, also take a look at: https://ericpony.github.io/z3py-tutorial/advanced-examples.htm. It does contain some quantification examples that can clarify things for you. (Even if you don't use the Python interface, I heartily recommend going over that page to see what the capabilities are. They more or less translate to SMTLib directly.)
Hope that gets you started. Stack-overflow works the best if you ask specific questions, so feel free to ask clarification on actual code as you need.
Semantically, a quantifier forall x: T . e(x) is equivalent to e(x_1) && e(x_2) && ..., where the x_i are all the values of type T. If T has infinitely many (or statically unknown many) values, then it is intuitively clear that an SMT solver cannot simply turn a quantifier into the equivalent conjunction.
The classical approach in this case are patterns (also called triggers), pioneered by Simplify and available in Z3 and others. The idea is rather simple: users annotate a quantifier with a syntactical pattern that serves a heuristic for when (and how) to instantiate the quantifier.
Here is an example (in pseudo-code):
assume forall x :: {foo(x)} foo(x) ==> false
Here, {foo(x)} is the pattern, indicating to the SMT solver that the quantifier should be instantiated whenever the solver gets a ground term foo(something). For example:
assume forall x :: {foo(x)} foo(x) ==> 0 < x
assume foo(y)
assert 0 < y
Since the ground term foo(y) matches the trigger foo(x) when the quantified variable x is instantiated with y, the solver will instantiate the quantifier accordingly and learn 0 < y.
Patterns and quantfier triggering is difficult, though. Consider this example:
assume forall x :: {foo(x)} (foo(x) || bar(x)) ==> 0 < y
assume bar(y)
assert 0 < y
Here, the quantifier won't be instantiated because the ground term bar(y) does not match the chosen pattern.
The previous example shows that patterns can cause incompletenesses. However, they can also cause termination problems. Consider this example:
assume forall x :: {f(x)} !f(x) || f(f(x))
assert f(y)
The pattern now admits a matching loop, which can cause nontermination. Ground term f(y) allows to instantiate the quantifier, which yields the ground term f(f(y)). Unfortunately, f(f(y)) matches the trigger (instantiate x with f(y)), which yields f(f(f(y))) ...
Patterns are dreaded by many and indeed tricky to get right. On the other hand, working out a triggering strategy (given a set of quantifiers, find patterns that allow the right instantiations, but ideally not more than these) ultimately "only" required logical reasoning and discipline.
Good starting points are:
* https://rise4fun.com/Z3/tutorial/, section "Quantifiers"
* http://moskal.me/smt/e-matching.pdf
* https://dl.acm.org/citation.cfm?id=1670416
* http://viper.ethz.ch/tutorial/, section "Quantifiers"
Z3 also has offers Model-based Quantifier Instantiation (MBQI), an approach to quantifiers that doesn't use patterns. As far as I know, it is unfortunately also much less well documented, but the Z3 tutorial has a short section on MBQI as well.

Change standard tex output of multiplication in maxima

We try to change the way maxima translates multiplication when converting to tex.
By default maxima gives a space: \,
We changed this to our own latex macro that looks like a space, but in that way we conserve the sementical meaning which makes it easier to convert the latex back to maxima.
:lisp (setf (get 'mtimes 'texsym) '("\\invisibletimes "));
However, we have one problem, and that is when we put simplification on. We use this for generating steps in the explanation of a solution. For example:
tex1(block([simp: false], 2*3));
Of course when multiplying numbers we can want an explicit multiplication (\cdot).
So we would like it that if both arguments of the multiplication are numbers, that we then have a \cdot when translating to tex.
Is that possible?
Yes, if there is a function named by the TEX property, that function is called to process an expression. The function named by TEX takes 3 arguments, namely an expression with the same operator to which the TEX property is attached, stuff to the left, and stuff to the right, and the TEX function returns a list of strings which are the bits of TeX which should be output.
You can say :lisp (trace tex-mtimes) to see how that works. You can see the functions attached to MTIMES or other operators by saying :lisp (symbol-plist 'mtimes) or in general :lisp (symbol-plist 'mfoo) for another MFOO operator.
So if you replace TEX-MTIMES (by :lisp (setf (get 'mtimes 'tex) 'my-tex-mtimes)) by some other function, then you can control the output to a greater extent. Here is an outline of a suitable function for your purpose:
(defun my-tex-mtimes (e l r)
(if $simp
(tex-nary e l r) ;; punt to default handler
(tex-mtimes-special-case e l r)))
You can make TEX-MTIMES-SPECIAL-CASE as complicated as you want. I assume that you can carry out the Lisp programming for that. The simplest thing to try, perhaps a point of departure for further efforts, is to just temporarily replace TEXSYM with \cdot. Something like:
(defun tex-mtimes-special-case (e l r)
(let ((prev-texsym (get 'mtimes 'texsym)))
(prog2 (setf (get 'mtimes 'texsym) (list "\\cdot "))
(tex-nary e l r)
(setf (get 'mtimes 'texsym) prev-texsym))))

Shallow and Deep Binding

I was trying to understand the concept of dynamic/static scope with deep and shallow binding. Below is the code-
(define x 0)
(define y 0)
(define (f z) (display ( + z y))
(define (g f) (let ((y 10)) (f x)))
(define (h) (let ((x 100)) (g f)))
(h)
I understand at dynamic scoping value of the caller function is used by the called function. So using dynamic binding I should get the answer- 110. Using static scoping I would get the answer 0. But I got these results without considering shallow or deep binding. What is shallow and deep binding and how will it change the result?
There's an example in these lecture notes 6. Names, Scopes, and Bindings: that explains the concepts, though I don't like their pseudo-code:
thres:integer
function older(p:person):boolean
return p.age>thres
procedure show(p:person, c:function)
thres:integer
thres:=20
if c(p)
write(p)
procedure main(p)
thres:=35
show(p, older)
As best I can tell, this would be the following in Scheme (with some, I hope, more descriptive names:
(define cutoff 0) ; a
(define (above-cutoff? person)
(> (age person) cutoff))
(define (display-if person predicate)
(let ((cutoff 20)) ; b
(if (predicate person)
(display person))))
(define (main person)
(let ((cutoff 35)) ; c
(display-if person above-cutoff?)))
With lexical scoping the cutoff in above-cutoff? always refers to binding a.
With dynamic scoping as it's implemented in Common Lisp (and most actual languages with dynamic scoping, I think), the value of cutoff in above-cutoff?, when used as the predicate in display-if, will refer to binding b, since that's the most recent on on the stack in that case. This is shallow binding.
So the remaining option is deep binding, and it has the effect of having the value of cutoff within above-cutoff? refer to binding c.
Now let's take a look at your example:
(define x 0)
(define y 0)
(define (f z) (display (+ z y))
(define (g f) (let ((y 10)) (f x)))
(define (h) (let ((x 100)) (g f)))
(h)
I'm going to add some newlines so that commenting is easier, and use a comment to mark each binding of each of the variables that gets bound more than once.
(define x 0) ; x0
(define y 0) ; y0
(define (f z) ; f0
(display (+ z y)))
(define (g f) ; f1
(let ((y 10)) ; y1
(f x)))
(define (h)
(let ((x 100)) ; x1
(g f)))
Note the f0 and f1 there. These are important, because in the deep binding, the current environment of a function passed as an argument is bound to that environment. That's important, because f is passed as a parameter to g within f. So, let's cover all the cases:
With lexical scoping, the result is 0. I think this is the simplest case.
With dynamic scoping and shallow binding the answer is 110. (The value of z is 100, and the value of y is 10.) That's the answer that you already know how to get.
Finally, dynamic scoping and deep binding, you get 100. Within h, you pass f as a parameter, and the current scope is captured to give us a function (lambda (z) (display (+ z 0))), which we'll call ff for sake of convenience. Once, you're in g, the call to the local variable f is actually a call to ff, which is called with the current value of x (from x1, 100), so you're printing (+ 100 0), which is 100.
Comments
As I said, I think the deep binding is sort of unusual, and I don't know whether many languages actually implement that. You could think of it as taking the function, checking whether it has any free variables, and then filling them in with values from the current dynamic environment. I don't think this actually gets used much in practice, and that's probably why you've received some comments asking about these terms. I do see that it could be useful in some circumstances, though. For instance, in Common Lisp, which has both lexical and dynamic (called 'special') variables, many of the system configuration parameters are dynamic. This means that you can do things like this to print in base 16 (since *print-radix* is a dynamic variable):
(let ((*print-radix* 16))
(print value))
But if you wanted to return a function that would print things in base 16, you can't do:
(let ((*print-radix* 16))
(lambda (value)
(print value)))
because someone could take that function, let's call it print16, and do:
(let ((*print-radix* 10))
(print16 value))
and the value would be printed in base 10. Deep binding would avoid that issue. That said, you can also avoid it with shallow binding; you just return
(lambda (value)
(let ((*print-radix* 16))
(print value)))
instead.
All that said, I think that this discussion gets kind of strange when it's talking about "passing functions as arguments". It's strange because in most languages, an expression is evaluated to produce a value. A variable is one type of expression, and the result of evaluating a variable is the expression of that variable. I emphasize "the" there, because that's how it is: a variable has a single value at any given time. This presentation of deep and shallow binding makes it gives a variable a different value depending on where it is evaluated. That seems pretty strange. What I think would make much more sense is if the discussions were about what you get back when you evaluate a lambda expression. Then you could ask "what will the values of the free variables in the lambda expression be"? The answer, in shallow binding, will be "whatever the dynamic values of those variables are when the function is called later. The answer, in deep binding, is "whatever the dynamic values of those variables are when the lambda expression is evaluated."
Then we wouldn't have to consider "functions being passed as arguments." The whole "functions being passed as arguments" is bizarre, because what happens when you pass a function as a parameter (capturing its dynamic environment) and whatever you're passing it to then passes it somewhere else? Is the dynamic environment supposed to get re-bound?
Related Questions and Answers
Dynamic Scoping - Deep Binding vs Shallow Binding
Shallow & Deep Binding - What would this program print?
Dynamic/Static scope with Deep/Shallow binding (exercises) (The answer to this question mentions that "Dynamic scope with deep binding is much trickier, since few widely-deployed languages support it.")

Streams and the substitution model

I am wondering how the substitution model can be used to show certain things about infinite streams. For example, say you have a stream that puts n in the nth spot and so on inductively. I define it below:
(define all-ints
(lambda ((n <integer>))
(stream-cons n (all-ints (+ 1 n)))))
(define integers (all-ints 1))
It is pretty clear that this does what it is supposed to, but how would someone go about proving it? I decided to use induction. Specifically, induction on k where
(last (stream-to-list integers k))
provides the last value of the first k values of the stream provided, in this case integers. I define stream-to-list below:
(define stream-to-list
(lambda ((s <stream>) (n <integer>))
(cond ((or (zero? n) (stream-empty? s)) '())
(else (cons (stream-first s)
(stream-to-list (stream-rest s) (- n 1)))))))
What I'd like to prove, specifically, is the property that k = (last (stream-to-list integers k)) for all k > 1.
Getting the base case is fairly easy and I can do that, but how would I go about showing the "inductive case" as thoroughly as possible? Since computing the item in the k+1th spot requires that the previous k items also be computed, I don't know how this could be shown. Could someone give me some hints?
In particular, if someone could explain how, exactly, streams are interpreted using the substitution model, I'd really appreciate it. I know they have to be different from the other constructs a regular student would have learned before streams, because they delay computation and I feel like that means they can't be evaluated completely. In turn this would man, I think, the substitution model's apply eval apply etc pattern would not be followed.
stream-cons is a special form. It equalent to wrapping both arguments in lambdas, making them thunks. like this:
(stream-cons n (all-ints (+ 1 n))) ; ==>
(cons (lambda () n) (lambda () (all-ints (+ n 1))))
These procedures are made with the lexical scopes so here n is the initial value while when forcing the tail would call all-ints again in a new lexical scope giving a new n that is then captured in the the next stream-cons. The procedures steam-first and stream-rest are something like this:
(define (stream-first s)
(if (null? (car s))
'()
((car s))))
(define (stream-rest s)
(if (null? (cdr s))
'()
((cdr s))))
Now all of this are half truths. The fact is they are not functional since they mutates (memoize) the value so the same value is not computed twice, but this is not a problem for the substitution model since side effects are off limits anyway. To get a feel for how it's really done see the SICP wizards in action. Notice that the original streams only delayed the tail while modern stream libraries delay both head and tail.

How to create a lazy-seq generating, anonymous recursive function in Clojure?

Edit: I discovered a partial answer to my own question in the process of writing this, but I think it can easily be improved upon so I will post it anyway. Maybe there's a better solution out there?
I am looking for an easy way to define recursive functions in a let form without resorting to letfn. This is probably an unreasonable request, but the reason I am looking for this technique is because I have a mix of data and recursive functions that depend on each other in a way requires a lot of nested let and letfn statements.
I wanted to write the recursive functions that generate lazy sequences like this (using the Fibonacci sequence as an example):
(let [fibs (lazy-cat [0 1] (map + fibs (rest fibs)))]
(take 10 fibs))
But it seems in clojure that fibs cannot use it's own symbol during binding. The obvious way around it is using letfn
(letfn [(fibo [] (lazy-cat [0 1] (map + (fibo) (rest (fibo)))))]
(take 10 (fibo)))
But as I said earlier this leads to a lot of cumbersome nesting and alternating let and letfn.
To do this without letfn and using just let, I started by writing something that uses what I think is the U-combinator (just heard of the concept today):
(let [fibs (fn [fi] (lazy-cat [0 1] (map + (fi fi) (rest (fi fi)))))]
(take 10 (fibs fibs)))
But how to get rid of the redundance of (fi fi)?
It was at this point when I discovered the answer to my own question after an hour of struggling and incrementally adding bits to the combinator Q.
(let [Q (fn [r] ((fn [f] (f f)) (fn [y] (r (fn [] (y y))))))
fibs (Q (fn [fi] (lazy-cat [0 1] (map + (fi) (rest (fi))))))]
(take 10 fibs))
What is this Q combinator called that I am using to define a recursive sequence? It looks like the Y combinator with no arguments x. Is it the same?
(defn Y [r]
((fn [f] (f f))
(fn [y] (r (fn [x] ((y y) x))))))
Is there another function in clojure.core or clojure.contrib that provides the functionality of Y or Q? I can't imagine what I just did was idiomatic...
letrec
I have written a letrec macro for Clojure recently, here's a Gist of it. It acts like Scheme's letrec (if you happen to know that), meaning that it's a cross between let and letfn: you can bind a set of names to mutually recursive values, without the need for those values to be functions (lazy sequences are ok too), as long as it is possible to evaluate the head of each item without referring to the others (that's Haskell -- or perhaps type-theoretic -- parlance; "head" here might stand e.g. for the lazy sequence object itself, with -- crucially! -- no forcing involved).
You can use it to write things like
(letrec [fibs (lazy-cat [0 1] (map + fibs (rest fibs)))]
fibs)
which is normally only possible at top level. See the Gist for more examples.
As pointed out in the question text, the above could be replaced with
(letfn [(fibs [] (lazy-cat [0 1] (map + (fibs) (rest (fibs)))))]
(fibs))
for the same result in exponential time; the letrec version has linear complexity (as does a top-level (def fibs (lazy-cat [0 1] (map + fibs (rest fibs)))) form).
iterate
Self-recursive seqs can often be constructed with iterate -- namely when a fixed range of look-behind suffices to compute any given element. See clojure.contrib.lazy-seqs for an example of how to compute fibs with iterate.
clojure.contrib.seq
c.c.seq provides an interesting function called rec-seq, enabling things like
(take 10 (cseq/rec-seq fibs (map + fibs (rest fibs))))
It has the limitation of only allowing one to construct a single self-recursive sequence, but it might be possible to lift from it's source some implementation ideas enabling more diverse scenarios. If a single self-recursive sequence not defined at top level is what you're after, this has to be the idiomatic solution.
combinators
As for combinators such as those displayed in the question text, it is important to note that they are hampered by the lack of TCO (tail call optimisation) on the JVM (and thus in Clojure, which elects to use the JVM's calling conventions directly for top performance).
top level
There's also the option of putting the mutually recursive "things" at top level, possibly in their own namespace. This doesn't work so great if those "things" need to be parameterised somehow, but namespaces can be created dynamically if need be (see clojure.contrib.with-ns for implementation ideas).
final comments
I'll readily admit that the letrec thing is far from idiomatic Clojure and I'd avoid using it in production code if anything else would do (and since there's always the top level option...). However, it is (IMO!) nice to play with and it appears to work well enough. I'm personally interested in finding out how much can be accomplished without letrec and to what degree a letrec macro makes things easier / cleaner... I haven't formed an opinion on that yet. So, here it is. Once again, for the single self-recursive seq case, iterate or contrib might be the best way to go.
fn takes an optional name argument with that name bound to the function in its body. Using this feature, you could write fibs as:
(def fibs ((fn generator [a b] (lazy-seq (cons a (generator b (+ a b))))) 0 1))

Resources