[LISP] Rekurencja

0

Witam mam problem z uruchomieniem kodu LISPa w dziwnym interpretatorze który jest wymagany na mojej uczelni

http://www.cs.auckland.ac.nz/CDMTCS/chaitin/unknowable/lisp.html to jest ten interpretator

###################################
Potęga
###################################

(defun potega (m n) (if (= n 0) 1 (* m (potega m (1- n)))))

###################################
Silnia
###################################

(defun silnia (n)
  (cond ((< n 2) n)
        (t (* n (silnia (- n 1))))
  )
) 
(silnia 5) 

###################################
Ciąg Fibonacciego
###################################

defun fib(n)
  (let ((a 0)
        (b 1)
        (tmp 0))
    (dotimes (x n a)
      (setq tmp a)
      (setq a b)
      (setq b (+ tmp b)))))

ten kod muszę jakoś przerobić z interakcji na rekurencję i nie mam pojęcia jak to zrobić
###################################

Pozdrawiam HELP [browar]

// poprawiłem tagi (dop. deus)

0

Cóż, powiedzieć, że ten interpreter jest dziwny to mało. A to Polska właśnie, na cywilizowanych uczelniach używa się CLispa jako interpreter Common Lispa bądź ew. MIT/GNU Scheme dla Scheme.
To coś Lispem nazwać trudno, podawany kod wiele wspólnego ze składnią Lispa nie ma - nawet podstawowej cechy mu brakuje - kod nie jest listą /tzn. jest.. ale nie jest jako lista zapisywany/. M-expy to głupota jakiej nigdy nie wprowadzi się oficjalnie do języka, dzięki Bogu kod z S-expami można ująć w "" i wtedy będzie traktowany normalanie... Generalnie to przypomina mocno obcięte Scheme.

bicluc napisał(a)
(defun potega (m n) (if (= n 0) 1 (* m (potega m (1- n)))))

Wygląda to na Common Lispa, cóż, przekształcić to będzie prosto - po prostu redukuje się nawiasy do minimum, do zachowania jednoznaczności. Zamiast defun daj define i tyle, tak jak w scheme. Inna sprawa, że w cywilizowanym Lispie operacje arytmetyczne czy logiczne przyjmują nieokreśloną liczbę argumentów np. (+ 3 4 62), tu zaś wyłącznie dwa - właśnie dla zachowania jednoznaczności.
define (potega m n) if <= n 0 1 * m (potega m - n 1)
Tyle... Bądź Twojego kodu całość ujmij w "", o tak:
"(define (potega m n) (if (<= n 0) 1 (* m (potega m - n 1))))"

bicluc napisał(a)
(defun silnia (n)
(cond ((< n 2) n)
(t (* n (silnia (- n 1))))
)
) 

Dwie sprawy - n! dla n < 2 /0 lub 1/ to 1, nie n. Druga to styl, typowy dla języków z rodziny C. W sumie i cond nie jest tutaj wybitnie pasującym rozwiązaniem - masz dokładnie dwie opcje - if.
define (silnia n) if < n 2 1 * n (silnia - n 1)

bicluc napisał(a)
defun fib(n)
(let ((a 0)
(b 1)
(tmp 0))
(dotimes (x n a)
(setq tmp a)
(setq a b)
(setq b (+ tmp b)))))

ten kod muszę jakoś przerobić z interakcji na rekurencję i nie mam pojęcia jak to zrobić

Chyba z iteracji nie, interakcji, z programowania imperatywnego na funkcyjne... Cóż, przerobić to na kod funkcyjny z zastosowaniem rekurencji ogonowej to nie problem... stworzyć lokalną funkcją aby a i b nie przekazywać publicznie i tyle. Z użyciem tych paskudnych M-expów:

define (fib n) 
   let (tail-fib n a b)
    if = n 0
     a
     (tail-fib - n 1 b + a b)
   (tail-fib n 0 1)

Hm, chyba działa :-)
Można wiedzieć co za uczelnia, gdzie się takiego syfu używa?

0

WSIZ w Rzeszowie a to tylko z tego powodu że nie da się zainstalować na komputerach nic normalnego a nie wprowadzili jeszcze wszędzie odpowiedniego oprogramowania. Na razie musimy się męczyć na czymś takim :-[

PS. Wielkie dzięki [browar]

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0