All possible sublists scheme - scheme

I want to find all possible consecutive partitions of a lists:
(a b c d) => (((a) (b c d)) ((a b) (c d)) ((a b c) (d)) ((a) (b c) (d)) ((a b c d)) ((a) (b) (c) (d)))
What would be the easiest way to go about this? ideally without using counters.
Edit:
Here is an example of what I have been trying, but it doesn't quite work (it is supposed to give the answers in reverse, but that'd be ok):
(define split-list-help
(lambda (l h a)
(begin
(display a)
(if
(null? (cdr l))
(list (cons (cons (car l) a) h))
(let
[(a-nosplit (cons (car l) a))
(h-split (if (null? a)
(cons (list (car l)) h)
(cons (list (car l)) (cons a h))))]
(append (split-list-help (cdr l) h-split '())
(split-list-help (cdr l) h a-nosplit)))))))
(split-list-help '(a b c) '() '())
The idea is that we traverse the list item by item, at each step we can either split it or not, then we branch into two new iterations, one with splitting and one without splitting. This produces a result close to what I want but not quite.

The goal is to find a natural way of describing the problem using recursion.
In order to find the sublists of (a b c d) we can focus on the element a.
There are four different consecutive sublists containing a:
(a) (a b) (a b c) (a b c d)
In each case we need to find the sublists of the remaining elements.
All in all the result must be the collection of list that result from
combining (a) with (sublists '(b c d))
combining (a b) with (sublists '(c d))
combining (a b c) with (sublists '(d))
combining (a b c d) with (sublists ' ())
That is we have:
(sublists '(a b c d)) = (append (combine '(a) (sublists '(b c d)))
(combine '(a b) (sublists '(c d)))
(combine '(a b c) (sublists '(d)))
(combine '(a b c d) (sublists '())))
We note that we have described the sublists of a list four elements
using a recursive call of sublists of only three elements.
The base case (sublists '()) must return the empty list '().
The only remaining question is what combine does.
Let's examine the relation between the input and ouput in the case
(combine '(a) (sublists '(b c d)))
The sublists of '(b c d) are:
( ((b) (c) (d))
((b) (c d) )
((b c) (d) )
((b c d) ) )
So (combine '(a) (sublists '(b c d))) must return
( ((a) (b) (c) (d))
((a) (b) (c d) )
((a) (b c) (d) )
((a) (b c d) ) )
The operation that preprends an element (the list '(a)) in front
of a list is cons, so we can use map and cons in concert:
(define (combine x xss)
(map (lambda (xs) (cons x xs)) ; function that prepends x to a list xs
xss))
Now we have all pieces of the puzzle. I'll leave the final definition
of sublists to you.

Since you mentioned miniKanren, here's a Prolog solution for this problem:
splits(L, LS):- % conde ...
( L = [] % L is empty list:
-> LS = []
; % OR
A = [_ | _], % A is non-empty,
append(A, B, L), % for each A, B such that A + B = L,
splits( B, BS), % for every splits BS of B,
LS = [ A | BS] % prepend A to BS to get the splits of L
).
%%% in SWI Prolog:
?- splits([1,2,3,4], R).
R = [[1], [2], [3], [4]] ;
R = [[1], [2], [3, 4]] ;
R = [[1], [2, 3], [4]] ;
R = [[1], [2, 3, 4]] ;
R = [[1, 2], [3], [4]] ;
R = [[1, 2], [3, 4]] ;
R = [[1, 2, 3], [4]] ;
R = [[1, 2, 3, 4]] ;
false.
Translated into miniKanren this would define splitso as a conde with an appendo and a recursive call to splitso:
#lang racket
(require minikanren)
(define (splitso L LS)
(conde
[(== L '()) (== LS '())]
[(fresh (A B BS _H _T)
(== A `(,_H . ,_T))
(appendo A B L)
(== LS `(,A . ,BS))
(splitso B BS))]))
;;;
> (run* (R) (splitso '(1 2 3 4) R))
'(((1 2 3 4))
((1) (2 3 4))
((1 2) (3 4))
((1) (2) (3 4))
((1 2 3) (4))
((1) (2 3) (4))
((1 2) (3) (4))
((1) (2) (3) (4)))
I copied appendo from here.
The order of solutions in miniKanren does not follow the order of goals in the predicate definition (as it does in Prolog), because miniKanren interleaves the results produced by sub-goals in order to achieve what it calls "fair scheduling".

Related

Retrieve nth cdr of a list in Scheme

I would like to return the nth cdr of a list. For example, I say
(nth-cdr 3 '(a b c d e)) and i would get (c d e) as output. I am not sure where I am going wrong with my code.
My approach is this. I will check if (= num 0) if it is, I will return the list. If not, I will recursively call nth-cdr and subtract 1 from num and cdr list
The code is this
(define arbitrary-cdr (lambda (num list)
(if (= num 0)
'()
(arbitrary-cdr (- num 1) (cdr list))
)))
However, I get this error when i try doing (arbitrary-cdr 3 ‘(a b c d e))
‘: undefined;
cannot reference an identifier before its definition
I am not sure what this means. When I say that, it means I hit the base case and would just like to return the list. I think my logic is correct though.
The first code that you posted was:
(define arbitrary-cdr
(lambda (num list)
(if (= num 0)
(list)
(arbitrary-cdr (- num 1) (cdr list)))))
The error that you received was:
scratch.rkt> (arbitrary-cdr 3 '(a b d c e))
; application: not a procedure;
; expected a procedure that can be applied to arguments
; given: '(c e)
The problem was that you used list as an argument to the arbitrary-cdr procedure; since Racket is a lisp-1, procedures do not have their own namespace, so this redefined list. With (list), and with list redefined the code attempted to call ((c e)), but (c e) is not a procedure.
This is a great example for why you should not use list or other built-in procedure identifiers as parameters in your own procedure definitions in Scheme or Racket. You can get away with this in Common Lisp, because Common Lisp is a lisp-2, i.e., has a separate namespace for functions.
With your updated code:
(define arbitrary-cdr
(lambda (num list)
(if (= num 0)
'()
(arbitrary-cdr (- num 1) (cdr list)))))
I don't get the error you report; maybe your code is not quite what you have posted. But, there is a mistake in the logic of your code. As it is, an empty list will always be returned:
scratch.rkt> (arbitrary-cdr 3 '(a b c d e f))
'()
The problem is that when the base case is reached you should return the input list, not an empty list. That is, given (arbitrary-cdr 0 '(a b c)), you want the result to be (a b c). This also means that your test case is wrong; (arbitrary-cdr 0 '(a b c d e)) --> '(a b c d e), and (arbitrary-cdr 3 '(a b c d e)) --> '(d e).
Here is your code rewritten, using xs instead of list to avoid the redefinition, and returning xs instead of an empty list when the base case is reached:
(define arbitrary-cdr
(lambda (num xs)
(if (= num 0)
xs
(arbitrary-cdr (- num 1) (cdr xs)))))
Sample interactions:
scratch.rkt> (arbitrary-cdr 0 '(a b c d e))
'(a b c d e)
scratch.rkt> (arbitrary-cdr 1 '(a b c d e))
'(b c d e)
scratch.rkt> (arbitrary-cdr 3 '(a b c d e))
'(d e)

Map function with index as one of arguments in LISP

Is there any built-in function in LISP languages (or Racket in particular) that would work like map, but pass index of the element as one of the arguments to the mapping function?
Example of such function would be:
(define map-index (lambda (func list)
(map func list (build-list (length list) (lambda (i) i)))))
;usage:
> (map-index cons '(a b c d))
;output:
'((a . 0) (b . 1) (c . 2) (d . 3))
Obviously this is not a very efficient implementation and doesn't support multiple lists as arguments, like regular map does.
Racket
You can write a dead-simple version of map-index using the Racket range procedure and mapping over the result:
(define (map-index-1 f xs)
(map f xs (range (length xs))))
In some situations you might want the indices first:
(define (map-index-2 f xs)
(map f (range (length xs)) xs))
If you want to be able to use map-index over multiple lists, you can pass the list arguments to an optional parameter. Here, apply applies the map procedure to a list constructed from the function f, the input lists, and a range list:
(define (map-index-3 f . xs)
(apply map (cons f
(append xs
(list (range (length (car xs))))))))
But it might make more sense to place the indices first when mapping over multiple lists:
(define (map-index-4 f . xs)
(apply map (cons f
(cons (range (length (car xs)))
xs))))
scratch.rkt> (map-index-1 cons '(a b c d))
'((a . 0) (b . 1) (c . 2) (d . 3))
scratch.rkt> (map-index-2 cons '(a b c d))
'((0 . a) (1 . b) (2 . c) (3 . d))
scratch.rkt> (map-index-3 list '(a b c d) '(one two three four) '(w x y z))
'((a one w 0) (b two x 1) (c three y 2) (d four z 3))
scratch.rkt> (map-index-4 list '(a b c d) '(one two three four) '(w x y z))
'((0 a one w) (1 b two x) (2 c three y) (3 d four z))
Scheme
Standard Scheme does not have a built-in range procedure, but it is easy enough to write a simple version. These solutions will work on any R4RS, R5RS, R6RS, or R7RS Scheme implementation. This version of range does more than is required for the current application, taking a step argument which can be positive or negative:
(define (range start stop step)
(if (or (and (> step 0)
(>= start stop))
(and (<= step 0)
(<= start stop)))
'()
(cons start (range (+ start step) stop step))))
Having defined a range procedure, the same approach used for the Racket solutions above can be used in Scheme:
(define (map-index-5 f xs)
(map f xs (range 0 (length xs) 1)))
(define (map-index-6 f xs)
(map f (range 0 (length xs) 1) xs))
(define (map-index-7 f . xs)
(apply map (cons f
(append xs
(list (range 0 (length (car xs)) 1))))))
(define (map-index-8 f . xs)
(apply map (cons f
(cons (range 0 (length (car xs)) 1)
xs))))
> (map-index-5 cons '(a b c d))
((a . 0) (b . 1) (c . 2) (d . 3))
> (map-index-6 cons '(a b c d))
((0 . a) (1 . b) (2 . c) (3 . d))
> (map-index-7 list '(a b c d) '(one two three four) '(w x y z))
((a one w 0) (b two x 1) (c three y 2) (d four z 3))
> (map-index-8 list '(a b c d) '(one two three four) '(w x y z))
((0 a one w) (1 b two x) (2 c three y) (3 d four z))
A map-range Procedure for Standard Scheme
This method can be extended to use numbers in a more complex range that may not represent indices by taking advantage of the capabilities of a range function. Using the range definition from above, this map-range procedure still works on R4RS to R7RS Scheme implementations:
(define (map-range f start step . xs)
(let ((stop (+ start (* step (length (car xs))))))
(apply map (cons f
(cons (range start stop step)
xs)))))
> (map-range cons 2 2 '(a b c d))
((2 . a) (4 . b) (6 . c) (8 . d))
> (map-range list 5 5 '(a b c d) '(one two three four) '(w x y z))
((5 a one w) (10 b two x) (15 c three y) (20 d four z))
> (map-range cons 2 -2 '(a b c d))
((2 . a) (0 . b) (-2 . c) (-4 . d))
> (map-range list 5 -5 '(a b c d) '(one two three four) '(w x y z))
((5 a one w) (0 b two x) (-5 c three y) (-10 d four z))
Not exactly, but there are other things for similar goals, like for/list with in-naturals or in-indexed.
For example instead of (map-index f lst), the pattern would be
(for/list ([x lst] [i (in-naturals)]) (f x i))
or
(for/list ([(x i) (in-indexed lst)]) (f x i))
And either of those patterns could be used to implement map-index as well as your combination of map and build-list.
Racket's iteration forms like for/list are more flexible than a fixed set of map-like functions.
Concrete Examples:
> (for/list ([x '(a b c d)] [i (in-naturals)]) (cons x i))
'((a . 0) (b . 1) (c . 2) (d . 3))
> (for/list ([(x i) (in-indexed '(a b c d))]) (cons x i))
'((a . 0) (b . 1) (c . 2) (d . 3))
Or if you still want a map-index function you could define it more succinctly using this.
> (define (map-index f lst)
(for/list ([(x i) (in-indexed lst)]) (f x i)))
> (map-index cons '(a b c d))
'((a . 0) (b . 1) (c . 2) (d . 3))

Scheme - generate all distinct permutations of a list

While reading a certain book about functional programming and scheme (and Racket) in particular, I happened upon an exercise which states the following:
`
"Write a function 'rp' which takes, as an argument, a list 'lp' of pairs '(a . n)',
where 'a' is either a symbol or a number and 'n' is a natural number,
and which returns the list of all the lists, whose elements are the 'a's defined by
the pairs in 'lp', each one appearing exactly 'n' times."
For some reason this is really cryptic, but what it basically asks for is the list of all distinct permutations of a list containing n times the number/symbol a.
E.g : [[(rp '((a . 2) (b . 1))]] = '((a a b) (a b a) (b a a))
Generating the permutations, ignoring the distinct part, is fairly easy since there is a, relatively, straight forward recursive definition:
The list of permutations of an empty list, is a list containing an empty list.
The list of permutations of 3 elements a b c is a list containing the lists of all permutations of
a and b where, for each one, c has been inserted in all possible positions.
Which I translated in the following racket code:
(define permut
(lambda(ls)
(if(null? ls) '(())
(apply append
(map (lambda(l) (insert_perm (car ls) l))
(permut (cdr ls)))))))
(define insert_perm
(lambda(x ls)
(if(null? ls) (list (list x))
(cons (cons x ls)
(map (lambda(l) (cons (car ls) l))
(insert_perm x (cdr ls)))))))
This works, but does not return distinct permutations. Taking into account the duplicates seems to me much more complicated. Is there a simple modification of the simple permutation case that I cannot see? Is the solution completely different? Any help would be appreciated.
The change is pretty simple. When you have no duplicate, the following works:
The list of permutations of 3 elements a b c is a list containing the lists of all permutations of a and b where, for each one, c has been inserted in all possible positions.
With duplicates, the above doesn't work anymore. A permutation of 2 elements a = "a", b = "b" is:
"a" "b"
"b" "a"
Now, consider c = "a". If you insert it in all possible positions, then you would get:
c "a" "b" = "a" "a" "b"
"a" c "b" = "a" "a" "b"
"a" "b" c = "a" "b" "a"
c "b" "a" = "a" "b" "a"
"b" c "a" = "b" "a" "a"
"b" "a" c = "b" "a" "a"
So instead, make a restriction that when you are inserting, you will only do it before the first occurrence of the same element that exists in the list that you are inserting to:
c "a" "b" = "a" "a" "b" -- this is OK. c comes before the first occurrence of "a"
"a" c "b" = "a" "a" "b" -- this is not OK. c comes after the first occurrence of "a"
"a" "b" c = "a" "b" "a" -- this is not OK
c "b" "a" = "a" "b" "a" -- this is OK
"b" c "a" = "b" "a" "a" -- this is OK
"b" "a" c = "b" "a" "a" -- this is not OK
This gives:
"a" "a" "b"
"a" "b" "a"
"b" "a" "a"
as desired.
Moreover, you can see that this algorithm is a generalization of the algorithm that doesn't work with duplicates. When there's no duplicate, there's no "first occurrence", so you are allowed to insert everywhere.
By the way, here's how I would format your code in Racket/Scheme style:
(define (permut ls)
(if (null? ls)
'(())
(apply append
(map (lambda (l) (insert-perm (car ls) l))
(permut (cdr ls))))))
(define (insert-perm x ls)
(if (null? ls)
(list (list x))
(cons (cons x ls)
(map (lambda (l) (cons (car ls) l))
(insert-perm x (cdr ls))))))
After some thought I came up with my own recursive definition that seems to work. This solution is an alternative to the one proposed in the answer by #Sorawee Porncharoenwase and can be defined as follows:
The distinct permutations of a list containing only one kind of element
(e.g '(a a a)) is the list itself.
if (f l) gives the list of distinct permutations (lists) of l,
where l contains x times each distinct element el_i, 0<=i<=n
and if ll is the list l plus one element el_i, 0<=i<=n+1 (distinct or not)
Then the distinct permutations of ll is a list containing
all the following possible concatenations:
el_i + (f l/{el_i}), where l/{el_i} is the list l excluding its ith distinct element.
To illustrate this definition, consider the following examples:
The list of all distinct permutations of (a b c) is the list containing
a + {(b c) (c b)} = (a b c) (a c b)
b + {(a c) (c a)} = (b a c) (b c a)
c + {(a b) (b a)} = (c a b) (c b a)
The list of all distinct permutations of (a a b) is the list containing:
a + {(a b) (b a)} = (a a b) (a b a)
b + {(a a)} = (b a a)
etc...
Similarly, the list of all distinct permutations of (a a b c) is:
a + {(a b c) ...} = (a a b c) (a a c b) (a b a c) (a b c a) (a c a b) (a c b a)
b + {(a a c) ...} = (a a c) (a c a) (c a a)
c + {(a a b) ...} = (a a b) (a b a) (b a a)
This leads to the following implementation:
(define unique_perm
(lambda(ls)
(if (= (length ls) 1)
(list (build-list (cdar ls) (const (caar ls))))
(apply append (map (lambda(p) (map (lambda(l) (cons (car p) l)) (unique_perm (update_ls ls p)))) ls)))))
(define update_ls
(lambda(ls p)
(cond ((null? ls) ls)
((equal? (caar ls) (car p))
(if (= (- (cdar ls) 1) 0)
(cdr ls)
(cons (cons (caar ls) (- (cdar ls) 1)) (cdr ls))))
(else (cons (car ls) (update_ls (cdr ls) p))))))
Example:
> (unique_perm_2 '((a . 3) (b . 2)))
'((a a a b b) (a a b a b) (a a b b a) (a b a a b) (a b a b a) (a b b a a) (b a a a b) (b a a b a) (b a b a a) (b b a a a))

Understanding map pattern for n-ary operations on n lists in Scheme

I understand that (map f '(a b c d)) is '(f(a) f(b) f(c) f(d)) by applying function f to each element in the list. But the following seems to be hard to understand for me:
(map * '(1 2) '(1 2))
The output should be '(1 4). How come?
Can anyone explain how map pattern works in Scheme when we apply an n-ary operation to n lists?
map takes the ith elements of the provided lists, passes them to the n-ary operation, and stores the result at ith position of the returned list.
So, (map f '(a b c d) '(A B C D)) will be equal to ((f a A) (f b B) (f c C) (f d D)).
More than two lists are handled similarly.
'(f (a) f (b) f (c) f (d)) is and can only be (f (a) f (b) f (c) f (d)) after evaluation.
map for one list argument can be defined like this:
(define (map1 fn lst)
(if (null? lst)
'()
(cons (fn (car lst))
(map1 fn (cdr lst)))))
and (map add1 '(1 2 3)) can be substituted with
(cons (add1 '1)
(cons (add1 '2)
(cons (add1 '3)
'())))
; ==> (2 . (3 . (4 . ())))
; ==> (2 3 4)
Now map takes at least one list argument and it expects the function passed to take one or each. Thus (map * '(1 2) '(1 2)) is the same as:
(cons (* '1 '1)
(cons (* '2 '2)
'()))
; ==> (1 . (4 . ()))
; ==> (1 4)
I'm not entirely sure if you are having trouble grasping map or how lists are made. If it is the latter you should really make it top priority to be able to see (1 2 (3 4)) and understand that 3 is the caaddr since the pairs are (1 . (2 . ((3 . (4 . ())) . ()))). Read it right to left while looking at the pairs and you see it. If it's map then you need to implement them. It is the best way to learn it.
To truly understand something is best to implement it ourselves.
The map for 1-argument functions is easy, it's
(define (map1 f1 xs)
(cons (f1 (car xs))
(map1 f1
(cdr xs))))
(adding the base case is left as an exercise). Similarly for two,
(define (map2 f2 xs ys)
(cons (f2 (car xs) (car ys))
(map2 f2
(cdr xs) (cdr ys))))
and three,
(define (map3 f3 xs ys zs)
(cons (f3 (car xs) (car ys) (car zs))
(map3 f3
(cdr xs) (cdr ys) (cdr zs))))
We can use the same template for any n-argument function to be mapped over any n lists to take the n arguments from:
map_n:
xs: x1 x2 x3 x4 x5 ...
ys: y1 y2 y3 y4 y5 ...
zs: z1 z2 z3 z4 z5 ...
...........................
↓ ↓ ↓ ↓ ↓
f f f f f
= = = = =
results: r1 r2 r3 r4 r5 ...
related: Matrix multiplication in scheme, List of lists

Scheme Difficulty Understanding output of my function 'concat lists' output

I wrote a function called 'my-append' which which takes two lists L1,L2
and appends each element of L2 to the end of L1. (in other words it concats L1 with L2)
the function seems to be behaving correctly however I seem to be getting a strange output.
(my-append '(a b '(1 2 3)) (list '(4 5 6) 7 8 9)) ==>
(list 'a 'b (list 'quote (list 1 2 3)) (list 4 5 6) 7 8 9)
I am new to scheme and cannot tell if this is correct or now.
Please note that I am using Advanced student language inside of dr racket.
Here is the code for the function. (it uses two helper functions)
;my-append
;takes two lists L1,L2 and returns concat of L2 to L1
;it first checks if either list is empty if so it returns the non empty one
;if both are empty returns empty
;if both are non empty determine which list has smaller length
;calls my-append-helper with first arg as smaller second larger
;append-element
;takes a list L and element x and adds x
; to the end of L
; I am super limited on which operations i can use
; so i must resort to this O(n) algorithm
;my-append-helper
;takes either two non empty lists L1 L2 then
;builds the concatenation of L1 L2
;by stripping of first element of L2
;and adding it to L1
(define (append-element L x)
(cond ((equal? L '())
(list x) )
(else
(cons (first L)
(append-element (rest L) x)))))
(define my-append-helper
(lambda (L1 L2)
(cond ( (equal? '() L2)
L1)
(else (my-append-helper (append-element L1 (first L2)) (rest L2))))))
(define my-append
(lambda (L1 L2)
(cond ( (and (equal? L1 '()) (equal? L2 '()))
'() )
( (equal? L1 '() )
L2 )
( (equal? L2 '() )
L1)
( else
(my-append-helper L1 L2)))))
Yes the output is correct.
> (my-append '(a b '(1 2 3)) (list '(4 5 6) 7 8 9))
(list 'a 'b (list 'quote (list 1 2 3)) (list 4 5 6) 7 8 9)
It is printed in the style so that when pasted back at the prompt the result is the same:
> (list 'a 'b (list 'quote (list 1 2 3)) (list 4 5 6) 7 8 9)
(list 'a 'b (list 'quote (list 1 2 3)) (list 4 5 6) 7 8 9) ; compare below vvvvv
How can we be sure it's OK? By doing the same with the two parts:
> '(a b '(1 2 3))
(list 'a 'b (list 'quote (list 1 2 3)))
; --------------------------------
> (list '(4 5 6) 7 8 9)
(list (list 4 5 6) 7 8 9) ; aligned vertically ^^^
; ------------------
The append just puts the two parts together into one list, turning
(list a b c ... n) (list o p q ... z)
into
(list a b c ... n o p q ... z)
or, symbolically ("in pseudocode"),
[a b c ... n] [o p q ... z] ; is turned into:
[a b c ... n o p q ... z]
About your algorithm. It appends the two lists by repeating the steps
[a b c ... n] [o p q ... z]
[a b c ... n] o [p q ... z]
[a b c ... n o] [q ... z]
until the second list is exhausted. Repeatedly appending an element at a list's end is well suited for languages with such primitive, like Clojure's conj, which is cheap to use. But in Scheme it is algorithmically disadvantageous because the repeated traversal over the first list to append the element to it leads to a quadratic behaviour w.r.t. the time complexity (the execution time will grow four-fold for a two-fold increase in the input data's size).
Another way of doing this is
[a b ... m n] [o p q ... z]
[a b ... m] n [o p q ... z]
[a b ... m] [n o p q ... z]
until the first list is used up:
(define my-append-helper
(lambda (L1 L2)
(cond ( (equal? '() L1)
L2)
(else (my-append-helper (but-last L1) (cons (last L1) L2))))))
; ^^^^ !
cons is cheap in Scheme, so that is good. But repeatedly removing an element from a list's end (with the yet-not-implemented but-last) is algorithmically disadvantageous because the repeated traversal over the first list to remove its last element leads to a quadratic behaviour w.r.t. the time complexity (the execution time will grow four-fold for a two-fold increase in the input data's size).
We're on the right track with the cons though, when we notice that the appending can progress by the steps
[a b ... m n] [o p q ... z]
( [a] [b ... m n] ) [o p q ... z]
[a] ( [b ... m n] [o p q ... z] )
................................
[a] [b ... m n o p q ... z]
[a b ... m n o p q ... z]
when we set aside the first element of the first list, append what's left, and then all that is left for us to do is to cons that first element onto the result!
Does this count?
(define (myappend lst1 lst2)
(cond
((null? lst2) lst1)
(else (myappend (cons lst1 (cons (car lst2) '())) (cdr lst2)))))
This is an iterative procedure (rather than recursive).
Note that if
List 2 is empty, you can simply return list1.
Since your base case requires you to return your list1, just use an invariant based proof where you define list1 to be the invariant.
If that doesn't work, let me know and I'll try helping you debug your code.

Resources