Hi,
On Wednesday, 12 June 2013 23:33:23 UTC+2, jpd wrote:
(...)
If you want to prevent the infinite recursion one idea is to keep track of which functions you already visited and refuse to visit them
again within walk-src.
I did a quick hack of your code to avoid this case (Note: I remove take and introduced zip; it's a personal choice, nothing better or worse):
(define zip
X Y -> [] where (or (empty? X) (empty? Y))
X Y -> (zip-help X Y []))
(define zip-help
X Y Acc -> (reverse Acc) where (or (empty? X) (empty? Y))
[X | Xs] [Y | Ys] Acc -> (zip-help Xs Ys [(@p X Y) | Acc]))
(define substitute
Old New List -> (map (/. X (if (cons? X) (substitute Old New X) (if (= X Old) New X))) List))
(define substitute-with-zip
[] List -> List
[(@p O N) | Rest] List -> (substitute-with-zip Rest (substitute O N List)))
(define function?
{A --> boolean}
X -> (not (= (arity X) -1)))
(define user-function?
F -> (and (function? F) (not (shen.sysfunc? F))))
(define kl-inline
Kl NewParams -> (let A (reverse Kl)
B (head (tail A))
C (head A)
(substitute-with-zip (zip B NewParams) C)))
(define walk-src
Code Survey -> (let Chase (/. X (walk-src X Survey))
UpdateChase (/. F X (walk-src X (cons F Survey)))
Fn (head Code)
(if (user-function? Fn)
(let Kl (ps Fn)
(if (empty? (intersection Kl Survey))
(UpdateChase Fn (kl-inline Kl (map Chase (tail Code))))
(cons Fn (map Chase (tail Code)))))
(map Chase Code))) where (cons? Code)
X _ -> X)
(defcc <kl-defun>
defun F A C := [defun F A (walk-src C [F])];)
(define ps-inline
F -> (compile <kl-defun> (ps F)))
\*
* Tests
*
*\
(define a
X Y -> (+ X Y))
(define b
0 -> 1
X -> (a 2 X))
(define c
0 -> 0
X -> (b X) where (< X 50)
X -> (- (b X) (a 5 X)))
(define pure-head
[X | Xs] -> (pure-head X)
X -> X)
(define even?
1 -> false
X -> (odd? (- X 1)))
(define odd?
0 -> false
X -> (even? (- X 1)))
(define safe-take-and-c
0 _ Acc -> (map (function c) (reverse Acc))
_ [] Acc -> (safe-take-and-c 0 _ Acc)
N [X | Xs] Acc -> (safe-take-and-c (- N 1) Xs [X | Acc]))
(ps-inline c) \* yields Kl code calling + and - primitives *\
(= (ps pure-head) (ps-inline pure-head)) \* true : don't walk in a simple recursion *\
(ps-inline even?) \* written using itself *\
(ps-inline safe-take-and-c) \* don't expand recursion but c as +/- primitives *\
\* eof *\
Hope it helps,
Cheers,
--
Martial