Deductive Retriever Example - lisp

In Lisp, suppose I have these two rules in the knowledge base:
(append nil ?x ?x)
(<- (append (cons ?x ?l1) ?l2 (cons ?x ?l3))
(append ?l1 ?l2 ?l3))
Then how could I infer that if we ask
(ask '(append (cons a (cons b nil))
(cons c nil)
?l)
'?l))
we will get the result '((cons a (cons b (cons c nil)))?
This is one example from my Lisp class, I hope you could help me understand this retriever.
Thank you.

To understand the problem, I think you'll need to acquire two key concepts first: backward chaining and unification.
With gross simplification, here is how backward chaining works: try if it is possible to unify the goal (the first argument for 'ask' in your example) with the head of any of the rules (note the nondeterminism); if yes, add the body (which may be empty) of that rule as subgoals and stash the result of unification (a set of variable bindings). Recursively apply the above procedure to each subgoal with the accumulated bindings until either (1) there is no applicable rule, which means the proof fails, or (2) there is no more subgoal, which means the proof succeeds. In the latter case, the binding of the target variable (second argument) would be the answer.

Related

What is atom in LISP?

I would like to have a clear understanding, what is 'Atom' in LISP?
Due to lispworks, 'atom - any object that is not a cons.'.
But this definition is not enough clear for me.
For example, in the code below:
(cadr
(caddar (cddddr L)))
Is 'L' an atom? On the one hand, L is not an atom, because it is cons, because it is the list (if we are talking about object, which is associated with the symbol L).
On the other hand, if we are talking about 'L' itself (not about its content, but about the symbol 'L'), it is an atom, because it is not a cons.
I've tried to call function 'atom',
(atom L) => NIL
(atom `L) => T
but still I have no clue... Please, help!
So the final question: in the code above, 'L' is an atom, or not?
P.S. I'm asking this question due to LISP course at my university, where we have a definition of 'simple expression' - it is an expression, which is atom or function call of one or two atomic parameters. Therefore I wonder if expression (cddddr L) is simple, which depends on whether 'L' is atomic parameter or not.
Your Lisp course's private definition of "simple expression" is almost certainly rooted purely in syntax. The idea of "atomic parameter" means that it's not a compound expression. It probably has nothing to do with the run-time value!
Thus, I'm guessing, these are simple expressions:
(+ 1 2)
42
"abc"
whereas these are not:
(+ 1 (* 3 4)) ;; (* 3 4) is not an atomic parameter
(+ a b c) ;; parameters atomic, but more than two
(foo) ;; not simple: fewer than one parameter, not "one or two"
In light of the last counterexample, it would probably behoove them to revise their definition.
On the one hand, L is not an atom, because it is cons, because it is the list (if we are talking about object, which is associated with the symbol L).
You are talking here about the meaning of the code being executed, its semantics. L here stands for a value, which is a list in your tests. At runtime you can inspect values and ask about their types.
On the other hand, if we are talking about 'L' itself (not about its content, but about the symbol 'L'), it is an atom, because it is not a cons.
Here you are looking at the types of the values that make up the syntax of your code, how it is being represented before even being evaluated (or compiled). You are manipulating a tree of symbols, one of them being L. In the source code, this is a symbol. It has no meaning by itself other than being a name.
Code is data
Lisp makes it easy to represent source code using values in the language itself, and easy to manipulate fragments of code at one point to build code that is executed later. This is often called homoiconicity, thought it is somewhat a touchy word because people don't always think the definition is precise enough to be useful. Another saying is "code is data", something that most language designers and programmers will agree to be true.
Lisp code can be built at runtime as follows (> is the prompt of the REPL, what follows is the result of evaluation):
> (list 'defun 'foo (list 'l) (list 'car 'l))
(DEFUN FOO (L) (CAR L))
The resulting form happens to be valid Common Lisp code, not just a generic list of values. If you evaluate it with (eval *), you will define a function named FOO that takes the first element of some list L.
NB. In Common Lisp the asterisk * is bound in the REPL to the last value being successfully returned.
Usually you don't build code like that, the Lisp reader turns a stream of characters into such a tree. For example:
> (read-from-string "(defun foo (l) (car l))")
(DEFUN FOO (L) (CAR L))
But the reader is called also implicitly in the REPL (that's the R in the acronym).
In such a tree of symbols, L is a symbol.
Evaluation model
When you call function FOO after it has been defined, you are evaluating the body of FOO in a context where L is bound to some value. And the rule for evaluating a symbol is to lookup the value it is bound to, and return that. This is the semantics of the code, which the runtime implements for you.
If you are using a simple interpreter, maybe the symbol L is present somewhere at runtime and its binding is looked up. Usually the code is not interpreted like that, it is possible to analyze it and transform it in an efficient way, during compilation. The result of compilation probably does not manipulate symbols anymore here, it just manipulates CPU registers and memory.
In all cases, asking for the type of L at this point is by definition of the semantics just asking the type for whatever value is bound to L in the context it appears.
An atom is anything that is not a cons cell
Really, the definition of atom is no more complex than that. A value in the language that is not a cons-cell is called an atom. This encompasses numbers, strings, everything.
Sometimes you evaluate a tree of symbols that happens to be code, but then the same rule applies.
Simple expressions
P.S. I'm asking this question due to LISP course at my university, where we have a definition of 'simple expression' - it is an expression, which is atom or function call of one or two atomic parameters. Therefore I wonder if expression (cddddr L) is simple, which depends on whether 'L' is atomic parameter or not.
In that course you are writing functions that analyze code. You are given a Lisp value and must decide if it is a simple expression or not.
You are not interested in any particular interpretation of the value being given, at no point you are going to traverse the value, see a a symbol and try to resolve it to a value: you are checking if the syntax is a valid simple expression or not.
Note also that the definitions in your course might be a bit different than the one from any particular exising flavor (this is not necessarily Common Lisp, or Scheme, but a toy LISP dialect). Follow in priority the definitions from your course.
Imagine we have a predicate which tells us if an object is not a number:
(not-number-p 3) -> NIL
(not-number-p "string") -> T
(let ((foo "another string))
(not-number-p foo)) -> T
(not-number '(1 2 3)) -> T
(not-number (first '(1 2 3)) -> NIL
We can define that as:
(defun not-number-p (object)
(not (numberp object))
Above is just the opposite of NUMBERP.
NUMBERP -> T if object is a number
NOT-NUMBER-P -> NIL if object is a number
Now imagine we have a predicate NOT-CONS-P, which tells us if an object is not a CONS cell.
(not-cons-p '(1 . 2)) -> NIL
(let ((c '(1 . 2)))
(not-cons-p c)) -> NIL
(not-cons-p 3) -> T
(let ((n 4))
(not-cons-p n)) -> T
(not-cons-p NIL) -> T
(not-cons-p 'NIL) -> T
(not-cons-p 'a-symbol) -> T
(not-cons-p #\space) -> T
The function NOT-CONS-P can be defined as:
(defun not-cons-p (object)
(if (consp object)
NIL
T))
Or shorter:
(defun not-cons-p (object)
(not (consp object))
The function NOT-CONS-P is traditionally called ATOM in Lisp.
In Common Lisp every object which is not a cons cell is called an atom. The function ATOM is a predicate.
See the Common Lisp HyperSpec: Function Atom
Your question:
(cadr (caddar (cddddr L)))
Is 'L' an atom?
How would we know that? L is a variable. What is the value of L?
(let ((L 10))
(atom L)) -> T
(let ((L (cons 1 2)))
(atom L) -> NIL
(atom l) answers this question:
-> is the value of L an atom
(atom l) does not answer this question:
-> is L an atom? L is a variable and in a function call the value of L is passed to the function ATOM.
If you want to ask if the symbol L is an atom, then you need to quote the symbol:
(atom 'L) -> T
(atom (quote L)) -> T
symbols are atoms. Actually everything is an atom, with the exception of cons cells.

Where's foldl1 and foldr1 in Racket?

Racket has only foldl and foldr, which require initial value. Haskell in addition has foldl1 and foldr1, which instead of applying a function on the initial value and the first element, applies to first and second element. Currently i implemented them as:
(define (foldl1 f xs)
(foldl f (first xs) (rest xs)))
Is there a better way?
There is a better way, just (require srfi/1) and use reduce and reduce-right. :-D
What you are describing looks like reduce in CL. Your procedure looks ok except it would fail if the list is empty.
Be aware that first and rest are not the same as car and cdr since they only work on proper lists. eg.
(first '(a b c d e . f))
;;==>
;;first: contract violation
;; expected: (and/c list? (not/c empty?))
;; given: '(a b c d e . f)
Now. For racket to signal here it must have traversed the whole list to make sure it ends with null and since it didn't it signaled an error. I did a small test and found out that sorting a 2 million list used 32% more time with first/rest.

SICP: Can or be defined in lisp as a syntactic transformation without gensym?

I am trying to solve the last part of question 4.4 of the Structure and Interpretation of computer programming; the task is to implement or as a syntactic transformation. Only elementary syntactic forms are defined; quote, if, begin, cond, define, apply and lambda.
(or a b ... c) is equal to the first true value or false if no value is true.
The way I want to approach it is to transform for example (or a b c) into
(if a a (if b b (if c c false)))
the problem with this is that a, b, and c would be evaluated twice, which could give incorrect results if any of them had side-effects. So I want something like a let
(let ((syma a))
(if syma syma (let ((symb b))
(if symb symb (let ((symc c))
(if (symc symc false)) )) )) )
and this in turn could be implemented via lambda as in Exercise 4.6. The problem now is determining symbols syma, symb and symc; if for example the expression b contains a reference to the variable syma, then the let will destroy the binding. Thus we must have that syma is a symbol not in b or c.
Now we hit a snag; the only way I can see out of this hole is to have symbols that cannot have been in any expression passed to eval. (This includes symbols that might have been passed in by other syntactic transformations).
However because I don't have direct access to the environment at the expression I'm not sure if there is any reasonable way of producing such symbols; I think Common Lisp has the function gensym for this purpose (which would mean sticking state in the metacircular interpreter, endangering any concurrent use).
Am I missing something? Is there a way to implement or without using gensym? I know that Scheme has it's own hygenic macro system, but I haven't grokked how it works and I'm not sure whether it's got a gensym underneath.
I think what you might want to do here is to transform to a syntactic expansion where the evaluation of the various forms aren't nested. You could do this, e.g., by wrapping each form as a lambda function and then the approach that you're using is fine. E.g., you can do turn something like
(or a b c)
into
(let ((l1 (lambda () a))
(l2 (lambda () b))
(l3 (lambda () c)))
(let ((v1 (l1)))
(if v1 v1
(let ((v2 (l2)))
(if v2 v2
(let ((v3 (l3)))
(if v3 v3
false)))))))
(Actually, the evaluation of the lambda function calls are still nested in the ifs and lets, but the definition of the lambda functions are in a location such that calling them in the nested ifs and lets doesn't cause any difficulty with captured bindings.) This doesn't address the issue of how you get the variables l1–l3 and v1–v3, but that doesn't matter so much, none of them are in scope for the bodies of the lambda functions, so you don't need to worry about whether they appear in the body or not. In fact, you can use the same variable for all the results:
(let ((l1 (lambda () a))
(l2 (lambda () b))
(l3 (lambda () c)))
(let ((v (l1)))
(if v v
(let ((v (l2)))
(if v v
(let ((v (l3)))
(if v v
false)))))))
At this point, you're really just doing loop unrolling of a more general form like:
(define (functional-or . functions)
(if (null? functions)
false
(let ((v ((first functions))))
(if v v
(functional-or (rest functions))))))
and the expansion of (or a b c) is simply
(functional-or (lambda () a) (lambda () b) (lambda () c))
This approach is also used in an answer to Why (apply and '(1 2 3)) doesn't work while (and 1 2 3) works in R5RS?. And none of this required any GENSYMing!
In SICP you are given two ways of implementing or. One that handles them as special forms which is trivial and one as derived expressions. I'm unsure if they actually thought you would see this as a problem, but you can do it by implementing gensym or altering variable? and how you make derived variables like this:
;; a unique tag to identify special variables
(define id (vector 'id))
;; a way to make such variable
(define (make-var x)
(list id x))
;; redefine variable? to handle macro-variables
(define (variable? exp)
(or (symbol? exp)
(tagged-list? exp id)))
;; makes combinations so that you don't evaluate
;; every part twice in case of side effects (set!)
(define (or->combination terms)
(if (null? terms)
'false
(let ((tmp (make-var 'tmp)))
(list (make-lambda (list tmp)
(list (make-if tmp
tmp
(or->combination (cdr terms)))))
(car terms)))))
;; My original version
;; This might not be good since it uses backquotes not introduced
;; until chapter 5 and uses features from exercise 4.6
;; Though, might be easier to read for some so I'll leave it.
(define (or->combination terms)
(if (null? terms)
'false
(let ((tmp (make-var 'tmp)))
`(let ((,tmp ,(car terms)))
(if ,tmp
,tmp
,(or->combination (cdr terms)))))))
How it works is that make-var creates a new list every time it is called, even with the same argument. Since it has id as it's first element variable? will identify it as a variable. Since it's a list it will only match in variable lookup with eq? if it is the same list, so several nested or->combination tmp-vars will all be seen as different by lookup-variable-value since (eq? (list) (list)) => #f and special variables being lists they will never shadow any symbol in code.
This is influenced by eiod, by Al Petrofsky, which implements syntax-rules in a similar manner. Unless you look at others implementations as spoilers you should give it a read.

Lisp - Elements of a lisp occur in other list

i'm having a problem with this lisp function. I want to create a function that receives two lists, and verifies if the elements of the first list (all of them) occur in the second list, it returns True if this happens.
Currently i have the following code:
(defun ocorre-listas (l1 l2)
(dolist (elem1 l1)
(dolist (elem2 l2)
(if (equal elem1 elem2)
t))))
It's not working, as expected. Should i try to do it just with a simple recursion? I'm really not getting how i can iterate both lists in search of equal elements.
I decided to try without the dolists. This is what i have now, it's still not working.
(defun ocorre-listas (l1 l2)
(cond ((null l1) nil)
((null l2) nil)
((if (/= (first l1)(first l2)) (ocorre-listas l1 (rest l2))))
(t (if (= (first l1) (first l2)) (ocorre-listas (rest l1)(rest l2))))))
I get a warning saying that "t" is an undefined function. Also, every example i try returns null. What am i doing wrong ?
In the second piece of code, if the first list is empty then all of its elements are in the second one.
You don't need the ifs since you are inside a cond
After test if the lists are empty, you'll only need to test if the first element of the first list is in the second one and call the function again with the first list without this element
Instead of trying to do everything in one function, consider splitting it into two (or more) functions, e.g.
One that takes a number and the second list, and tests whether the number appears in the list
Another that iterates over the numbers in the first list, and for each one tests (using the first function) whether it appears in the second list.
As well as DOLIST, consider using MAPCAR and FIND-IF (assuming they are allowed in this assignment.)
So you need to check if every element of l1 is a member of l2. These are both functions in the Common Lisp standard library, so if you're allowed to use them, you can build a simple solution with them.
See the common lisp subsetp
predicate and its implementation:
CL-USER> (subsetp '(1 2 3) '(1 2 3 4)
T
To be able to work on both lists at the same time, the trick is probably to sort the lists before starting the recursion. Then it should be a simple matter of comparing the first element, and applying the same function to the rest of the list recursively, with some CAR/CDR magic added of course...
While there are many ways to do this, I would recommend using a hash table to avoid O(n^2) complexity. Using a hash table, you can achieve O(n) complexity.
here is a union function
(defun my-union (a b)
(let ((h (make-hash-table :test #'equal)))
(mapcar (lambda (x) (setf (gethash x h) x)) a)
(mapcan (lambda (x) (when (gethash x h) (list x))) b)))
here is a function testing for IDENTICAL elements in boths lists
(defun same-elements (a b)
(apply #'= (mapcar #'length (list (my-union a b) a b))))
here is a function making sure a is a subset of b (what you asked)
(defun subset (a b)
(same-elements (my-union a b) a))

How do I apply "or" to a list in elisp

In elisp I can evaluate or as a function just like +.
(or nil 0 nil) ==> 0
(+ 1 0 1) ==> 2
I can use apply to apply + to a list
(apply '+ '(1 0 1)) ==> 2
So, I would think or would work the same way, but it doesn't.
(apply 'or '(nil 0 nil)) ==> error: (invalid-function or)
I imagine this comes from some internal magic used to implement the short-circuit evaluation. How can I use apply to execute the or operation over a list?
P.S. my desired application is to find out whether any elements on the command line match a particular pattern, so the important part of what I am writing is:
(apply 'or (mapcar (lambda (x) (string-match-p "pattern" x)) command-line-args))
But it doesn't work
The problem is that or is a macro (which is the "internal magic" in question), and you're right that that's done so it can do short-circuiting. If or was a function, then calling it would need to follow the usual rules for evaluating a function call: all the arguments would need to get evaluated before the call is made.
See also this question -- it's about Scheme but it's the exact same issue.
As for a solution, you should probably use some, as in:
(some (lambda (x) (string-match-p "pattern" x)) command-line-args)
Note: this uses common lisp that is not included in emacs by default. Just use (require 'cl)
If it makes you feel any better, you're in good company! This is the third question in the "Common Pitfalls" section of the Lisp FAQ:
Here's the simple, but not necessarily satisfying, answer: AND and OR are
macros, not functions; APPLY and FUNCALL can only be used to invoke
functions, not macros and special operators.
...and Eli is of course right on the money with his suggestion to use SOME:
The Common Lisp functions EVERY and SOME can be used to get the
functionality you intend when trying to apply #'AND and #'OR.
(The FAQ and this answer are mostly about Common Lisp but in this case if you omit the # character the answer is the same.)
If you don't care performance, use (eval (cons 'or '(nil 0 nil)))
When I was trying to 'apply' a macro to an argument list, I got an error that the function is unbound, which means that, 'apply' only receives a function, instead of a macro, as its first argument.
In order to fix this, I wrote a new function 'apply-macro' as follows:
(defun apply-macro (macro arg-list)
(eval
`(,macro ,#(loop for arg in arg-list
collect `(quote ,arg)))))
For instance, I wrote a macro to concatenate multiple lists together:
(defmacro conc-lists (&rest lists)
`(funcall #'concatenate 'list ,#lists))
e.g.
(conc-lists '(a b) '(c d) '(e f)) ;;=> (A B C D E F)
Now try 'apply-macro':
(apply-macro 'conc-lists '((a b) (c d) (e f)))
It works and returns the same output.
In fact, it will be expanded into:
(eval
(conc-lists (quote (a b)) (quote (c d)) (quote (e f))))
You can also pass a form to a macro:
(apply-macro 'conc-lists (maplist #'list '(a b c)))
;;=> ((A B C) (B C) (C))
Get back to your question, it's solved:
(apply-macro 'or '(nil 0 nil)) ;;=> 0
I'm only guessing here, but I think or might be one of these 20-odd 'functions' in lisp that are not really functions, since they don't always evaluate all parameters.
This makes sense to make or one of these, since if you have found one TRUE, you can stop searching. In other words, or is not a function as a form of optimization. Still only guessing though.
Eli Barzilay's answer is correct and idiomatic. I want to provide an alternative answer based on dash.el, the library I use to write terse functional-style code, when I have to work with lists. or returns the first non-nil element, nil otherwise, due to short-circuiting. Therefore simply use -first:
(-first 'identity '(nil 0 1 nil)) ; 0
(-first 'identity '(nil nil)) ; nil
identity function simply returns its argument. Which is clever, because -first applies a predicate until it returns non-nil. identity returns non-nil if the argument is itself non-nil. If you simply want to test whether there is non-nil elements in a list, use -any? instead:
(-any? 'identity '(nil 0 1 nil)) ; t
(-any? 'identity '(nil nil)) ; nil