How to "de-nest" some nested lists - common-lisp

I have a recursive function that gives me this answer:
'((()) (((((a c d f e d))))) (((((a c d e f d))))))
Besides the fact that I need to look through the function in order to clean it up, that raises me the question: how to clean this answer up? How to "de-nest" those lists in order to return this:
'((a c d f e d) (a c d e f d))
I need some strategy or appropriate function in Racket or in Common Lisp.
Thanks in advance!

The behavior you want is a little bit unclear—if you just want to flatten a list, in Racket, you would just use the flatten function:
> (flatten '((()) (((((a c d f e d))))) (((((a c d e f d)))))))
'(a c d f e d a c d e f d)
However, it looks like you want to flatten each sublist, in which case you would want to just use map paired with flatten:
> (map flatten '((()) (((((a c d f e d))))) (((((a c d e f d)))))))
'(() (a c d f e d) (a c d e f d))
However, this still leaves the first empty list, which in your question it looks like you would like to remove. In that case, I would just add an additional filter step after flattening:
> (filter (negate empty?) (map flatten '((()) (((((a c d f e d))))) (((((a c d e f d))))))))
'((a c d f e d) (a c d e f d))
You could wrap this into a simple function that has the behavior you want:
(define (flatten-non-empty-sublists lst)
(filter (negate empty?) (map flatten lst)))

In common lisp, you can get the flatten function from alexandria, which you can get from quicklisp.

Related

Show that term `cons` works by showing all beta reductions

I'm new to functional programming.
So the terms cons appends an element to the front of the list. Where
cons ≜ λx:λl:λc:λn: c x (l c n)
How should I go about proving that cons works correctly using beta reduction for a sample function call? For example reducing cons 3 [2,1] to [3,2,1]?
Is there a formula like for the arithmetic operations in lambda calculus? I'm a bit confused on how to approach this compared to an arithmetic operation (i.e. addition or multiplication).
Thanks.
cons ≜ λx:λl:λc:λn: c x (l c n) means that
cons x l c n =
c x (l c n)
(in functional / applicative / combinatory notation). So
cons 3 [2,1] c n =
= c 3 ([2,1] c n)
and what is [2,1] if not just shortcut notation for cons 2 [1] so that we continue
= c 3 (cons 2 [1] c n)
= c 3 (c 2 ([1] c n))
= c 3 (c 2 (cons 1 [] c n))
= c 3 (c 2 (c 1 ([] c n)))
So there's no reduction from cons 3 [2,1] to [3,2,1]; [3,2,1] is cons 3 [2,1]. And [2,1] is cons 2 [1], and [1] is cons 1 [].
The list cons x xs, when supplied with c and n arguments, will turn into c x (xs c n), and so will xs, in its turn; so any list's elements are used in the chain of applications of c on top one another.
And what should [] c n turn into? It has nothing in it to put through the c applications -- those are to be applied to a list's elements, and [] has none. So the only reasonable thing to do (and I'm sure you're already given that definition) is to turn [] c n into just n:
cons 3 [2,1] c n =
= c 3 (c 2 (c 1 ([] c n)))
= c 3 (c 2 (c 1 n ))
whatever c and n are.
And that's that.

How to go count all of the atoms in a list (or a list of nested lists) when you use recursion

I am creating a recursive function that counts the number of atoms inside a list. It should be able to count the atoms of lists that are nested.
For example: (a (b c) e d) or (a (b c (g e)) e d), it should count b and c separately or b, c, e, and d separately and not as a whole.
This is the function that I have created:
(defun count-atoms (mylist)
(cond
((null mylist) 0)
((listp (car mylist)) (count-atoms (car mylist)))
((atom (car mylist)) (+ 1 (count-atoms (rest mylist))))
)
)
The output I get is 3 but it should be 5 (based from (a (b c) e d)). I am guessing that the function stops the moment it reaches c. How do i make the function not stop at c and make it go back to the outermost list.
Here's a way we can reason about the problem -
If the input is null, return zero
'( )
^
| 0 atoms
(inductive) Otherwise the input has at least one element. If car is a list, call count-elements on car and cdr. Add the two results together and return.
'( a b c d ... )
^ ^
| | count atoms in cdr <-
| \
| count atoms in sublist <------\_ add together
(inductive) Otherwise the input has at least one element that is not a list. Call count-elements on cdr. Add one to the result and return.
'( a b c d ... )
^ ^
| | count atoms in cdr <-
| \
| one atom <-----------------\_ add together
Do you see where your program differs?
Your mistake is that you are ignoring the tail in the second clause.
(defun count-atoms (tree)
"Count atoms in all leaves of the tree, ignoring terminating NIL."
(if tree
(+ (if (atom (car tree))
1
(count-atoms (car tree)))
(count-atoms (cdr tree)))
0))
now
(count-atoms '(a (b c) e d))
==> 5
(count-atoms '(a (b c (g e)) e d))
==> 7
(count-atoms '(a (b c (g e)) nil e d))
==> 8

Pseudocode: Understanding constraints let ... in

I'm reading a book about constraint based static code analysis. (Name: principles of program analysis) In there I found this code snippet:
let f = fn x => x 7
g = fn y => y
h = fn z => 3
in f g + f (g h)
It will be interpreted as:
f g + f (g h)
| |
v v
g 7 f h
|
v
h 7
I understand why f g will be g 7.
But why is f (g h) interpreted as f h? It should be g h 3, shouldn't it?
In expression f (g h) first g h is interpreted as h (according to g definition) and than f is applied.

Finding the diagonals of square matrix made from lists

I am currently trying to define a function that takes a list of lists, models that list as a square matrix and returns the diagonal of said matrix.
For example, input ((a b c) (d e f) (g h i)) gives (a e i).
I have a vague idea of how to go about solving this (taking the last element of the last list then the second to last element of the second to last list etc.) but I am not really sure of how to go about programming this in Scheme.
I would appreciate it if somebody could point me in the right direction.
Thanks.
(With apologies to Nethack fans)
As you step back from the altar, you find a little piece of paper lying on the floor from which you can decipher the following text:
0> Calling (DIAG ((A B C) (D E F) (G H I)))
1> Calling (DIAG ((E F) (H I)))
2> Calling (DIAG ((I)))
3> Calling (DIAG NIL)
<3 DIAG returned NIL
<2 DIAG returned (I)
<1 DIAG returned (E I)
<0 DIAG returned (A E I)
This looks good, but as you start reading the scroll aloud, you smell a foul scent of garbage nearby.
With the help of your wand of metamorphosis, you zap the cursed object.
The previous text vanishes and another one appears:
0> Calling (DIAG ((A B C) (D E F) (G H I)))
1> Calling (DIAG% ((A B C) (D E F) (G H I)) 0)
2> Calling (DIAG% ((D E F) (G H I)) 1)
3> Calling (DIAG% ((G H I)) 2)
4> Calling (DIAG% NIL 3)
<4 DIAG% returned NIL
<3 DIAG% returned (I)
<2 DIAG% returned (E I)
<1 DIAG% returned (A E I)
<0 DIAG returned (A E I)
A lit field surrounds you!

Isabelle: understanding the use of quantifiers

I have found that I can prove the following lemma, which seems false to me.
lemma assumes "∀a b. f a > f b ∧ a ≠ b"
shows "∀a b. f b > f a"
using assms by auto
How can the lemma above be true? Is Isabelle substituting values as I have used the ∀ quantifier? If so, I want to state the for all values of a and b, f(a) is greater than f(b), how would I do this?
Why does it seem false? You are stating that for ANY a and b, f a > f b and a ≠ b. This means that if say a = 0 and b = 1 then f 0 > f 1 but also when a = 1 and b = 0 it means that f 1 > f 0.
Furthermore, you assume ∀a b. f a > f b ∧ a ≠ b is true, this means you ASSUME that for any a and b, f a > f b AND a different from b. This is generally false as you can not have ∀a b. a ≠ b
Maybe what you meant to say was: ∀a b. (a ≠ b ==> f a > f b)? eg. for any a and b, if a ≠ b then f a > f b? Note that this still implies f b > f a as per the example above, it it really isn't saying anything meaningful.
The lemma you state is trivially true. Almost a direct instance of "A ==> A". From your assumption it may trivially be concluded that ∀a b. f a > f b. Then by renaming bound variables appropriately we obtain ∀b a. f b > f a. Moreover all-quantifiers may be reordered to obtain ∀a b. f b > f a.

Resources