两个列表之间的操作

时间:2013-09-08 18:05:44

标签: map lisp acl2

在常见的lisp中有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的语言应该自然而然地让你专门为它创建另一个函数,因此我要问的原因。

3 个答案:

答案 0 :(得分: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 :(得分:0)

ACL2基于一阶逻辑。在一阶逻辑中,语句如

(定义(P R A)(R A))

不允许

,因为R既被用作参数又被用作函数。

理论上可能通过在包含高阶逻辑构造的一阶逻辑中字面定义自己的语言来解决这个限制。否则,你是对的,你最好的选择是每次想要使用地图函数时定义除二 - 列表之类的东西。

这很乏味,但它是如何使用ACL2的。

答案 2 :(得分:0)

这并不完全适合您的问题,但它是相关的,因此我提及它以防其他人正在查看您的问题。

考虑一下这本书" std / util / defprojection",它提供了一个宏,可以让你在一个列表中映射一个函数。