2013-09-08 3 views
1

В общей шепелявости существует map, что позволяет делать такие вещи:операция между двумя списками

(map (lambda (x y) (/ x y)) (list 2 4 6 8 10 12) (list 1 2 3 4 5 6)) 

возвращающимся (2 2 2 2 2 2)

Однако сейчас я работаю в ACL2 и нет такой вещи как map. Так что, на мой взгляд, единственный выбор, который у меня есть, - это рекурсия, чтобы рассчитать то, что я хочу, если нет другого более простого и/или более эффективного способа сделать это.

... Это точно мой вопрос. Есть ли лучший способ сделать это, чем создать рекурсивную функцию, называемую чем-то вроде divide-two-lists? Это просто похоже на то, что естественный язык на основе lisp должен делать, а не создавать для вас другую функцию специально для этого, поэтому я спрашиваю.

+0

ACL2 ограничен, чтобы не поддерживать многие типичные функции Lisp по дизайну, а функции более высокого порядка относятся к тем функциям, которые были вырезаны. –

ответ

0

Вы могли бы легко написать свою собственную карту. Из GNU Emacs guide:

(defun mapcar* (function &rest args) 
    "Apply FUNCTION to successive cars of all ARGS. 
      Return the list of results." 
    ;; If no list is exhausted, 
    (if (not (memq nil args)) 
     ;; apply function to cars. 
     (cons (apply function (mapcar 'car args)) 
      (apply 'mapcar* function 
        ;; Recurse for rest of elements. 
        (mapcar 'cdr args))))) 

(mapcar* 'cons '(a b c) '(1 2 3 4)) 
⇒ ((a . 1) (b . 2) (c . 3)) 

Я незнаком с ACL2, так что вы, возможно, придется изменить некоторые функции (например, memq), или по-другому дело с тем, как работают apply или &rest аргументы, но это мясо кода ,

+1

ACL2 - это ограниченная версия Common Lisp, в которой явно отсутствуют такие операторы, как 'funcall' или' apply' (между прочим), поэтому в этом случае в других Lisp-файлах это невозможно. (Я бы сказал, что это не Lisp, хотя он использует синтаксис Lisp.) –

+0

Чтобы уточнить, что я сказал в начале моего предыдущего комментария, это не просто ограниченная версия CL. Он также предоставляет функции, которые CL нет. –

0

ACL2 основан на логике первого порядка. В логике первого порядка, высказывания типа

(определяют (П Р А) (R A))

не допускается, так как R используется и как параметр и функции.

теоретически можно обойти это ограничение, буквально определяя свой собственный язык в логике первого порядка, который включает в себя конструкции для логики более высокого порядка. В противном случае вы правы, ваш лучший вариант - определить что-то вроде divide-two-lists каждый раз, когда вы хотите использовать функцию карты.

Это утомительно, но именно так должен был использоваться ACL2.

0

Это не совсем подходит для вашего вопроса, но это связано, и поэтому я упоминаю об этом, если он помогает кому-то, кто смотрит на ваш вопрос.

Рассмотрите книгу «std/util/defprojection», которая предоставляет макрос, который позволяет сопоставить функцию по списку.