Запуск Python функций в CLISP - PullRequest
0 голосов
/ 18 апреля 2020

Доступны ли какие-либо источники CLISP? Я мог только найти ссылки на стек.

Я пытаюсь запустить определение python в CLISP - какие-либо предложения о том, как я go об этом? Я довольно хорошо знаком с написанием определений в CLISP, но не для python ... для начала я хочу переписать это из python:

def f(x):
if x <= 1/2:
    return 2 * x
if x > 1/2:
    return 2*x - 1

Просто чтобы посмотреть, как CLISP работает с вычисление дробей в качестве сравнения Я собирался провести это, которое я взял из онлайн курса по вычислительной алгебре:

x = 1/10
for i in range(80):
    print(x)
    x = f(x)

Благодарен за любые предложения ...

Приветствия.

1 Ответ

3 голосов
/ 18 апреля 2020

Так что я не совсем понимаю, чего вы пытаетесь достичь, но давайте сначала попробуем запустить пример Python. В настоящее время он плохо отформатирован (возможно, возникла проблема с копированием-вставкой), поэтому здесь с правильным отступом:

def f(x):
    if (x <= 1/2):
        return 2 * x
    else:
        return (2 * x) - 1

x = 1/10
for i in range(80):
    print(x)
    x = f(x)

В Python 2 это печатает только нули, потому что вы не работаете с рациональные числа , но просто делим целочисленное деление, которое усекается до нуля (с последующим умножением на 2). В Python 3 результатом будет серия чисел с плавающей точкой, сходящихся к 1.0, потому что числа с плавающей точкой приблизительны (спасибо @ex nihilo).

CLISP - это одна конкретная c реализация Стандарт Common Lisp, среди прочих (в произвольном порядке Lispworks, ECL, SBCL, Allegro CL, Clozure Common Lisp, ABCL, CL ASP, ...). Обычно Common Lisp - это аббревиатура CL, или иногда просто Lisp (это довольно противоречивое мнение), по той причине, что другие ветви семьи решили следовать совершенно другим философиям и были названы по-разному (Scheme, Clojure или даже Julia). Однако все они принадлежат к «семейству Lisp» языков.

Если под CLISP вы подразумеваете Common Lisp, то идиоматический c способ кодирования этого будет:

(defun f (x)
  (if (<= x 1/2)
      (* 2 x)
      (1- (* 2 x))))

(loop
   for i below 80
   for x = 1/10 then (f x)
   collect x)

Это оценивает (*) :

(1/10 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 
      1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 
      1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5
      1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5
      1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5 3/5 1/5 2/5 4/5)

Поэтому, если вы хотите что-то эквивалентное в Python, вам нужно использовать дроби:

from fractions import Fraction

def f(x):
    if (x <= Fraction(1, 2)):
        return 2 * x
    else:
        return (2 * x) - 1

x = Fraction(1,10)
r = list()
for i in range(80):
    r.append(x)
    x = f(x)

Полученный список:

[Fraction(1, 10), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5), Fraction(3, 5), Fraction(1, 5), Fraction(2, 5), Fraction(4, 5)]

(*) , но

(loop
   for i below 80
   for x = 0.1 then (f x)
   collect x)

оценивается как

(0.1 0.2 0.4 0.8 0.6 0.20000005 0.4000001 0.8000002 0.6000004 0.20000076
 0.40000153 0.80000305 0.6000061 0.2000122 0.4000244 0.8000488 0.60009766
 0.20019531 0.40039063 0.80078125 0.6015625 0.203125 0.40625 0.8125 0.625 0.25
 0.5 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0)

и преобразование его обратно в рациональные значения показывает, что оно будет

(13421773/134217728 13421773/67108864 13421773/33554432 13421773/16777216
 5033165/8388608 838861/4194304 838861/2097152 838861/1048576 314573/524288
 52429/262144 52429/131072 52429/65536 19661/32768 3277/16384 3277/8192 
 3277/4096 1229/2048 205/1024 205/512 205/256 77/128 13/64 13/32 13/16 5/8 
 1/4 1/2 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 
 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 
 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1)

Действительно, если мы используем 13421773/134217728 в качестве начальной точки в l oop, результирующая последовательность будет точно такой же.

...