找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 6771|回复: 31

[研讨] 勿在浮沙筑高台--由LISP公理推导函数的几个练习

[复制链接]

已领礼包: 8121个

财富等级: 富甲天下

发表于 2013-5-19 11:20:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 Highflybird 于 2013-6-1 17:23 编辑

此次练习由下面的帖子所引发:
http://bbs.xdcad.net/thread-668169-1-1.html

这些练习题的要求,形成的函数中只用到 quote atom cond eq car cdr cons 这七个基本函数和它们组合的函数构成:

附加说明: setq,defun,lambda,function,and,not,null,or 这几个也可以作为基本函数。当然,and,not,null,or 这几个函数也可以由七个公理推出。你不妨也去练习一下这四个逻辑判断函数。
apply ,eval,mapcar不能直接使用,除非你用基本函数去定义它们。
练习题1:
=============================================
Subst#
(为区别lisp原有的函数名,我在函数的名后面加了个#)
这个函数跟subst 类似,但又不同。
函数功能是替换,就是把表中的指定的项全部替换:(可能嵌套)
例如:
(subst# 'm 'b '(a b (a b c) d))
==> (a m (a m c) d)

当然,对数据也行:
(subst# 2 3  (list 1 (list 2 (list 3 2 5) 6 3 7) 2 3))
==> (1 (2 (2 2 5) 6 2 7) 2 2)



练习题2:
=============================================
Append#
这个函数跟append相同。取两个表并返回它们的连结.
(append# '(a b) '(c d))
==>(a b c d)
(append# '() '(c d))
==>(c d)
练习题3:
=============================================
Pair
(pair. x y)取两个相同长度的表,返回一个由双元素表构成的表,双元素表是相 应位置的x,y的元素对.
例如:
(pair. '(x y z) '(a b c))   
==>((x a) (y b) (z c))

练习题4:
=============================================
Assoc#
(assoc# x y)取原子x和形如pair.函数所返回的表y,返回y中第一个符合如下条 件的表的第二个元素:它的第一个元素是x.
例如: (assoc# 'x '((x a) (y b)))  
==>a  
(assoc#  'x '((x new) (x a) (y b)))  
==>new


以后慢慢添加。。









评分

参与人数 3D豆 +13 收起 理由
xshrimp + 5 出题引导交流奖!
炫翔 + 5 出题引导交流奖!
牢固 + 3 好主题奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 8121个

财富等级: 富甲天下

 楼主| 发表于 2013-5-19 11:36:37 | 显示全部楼层

嗯,如果不能自己思考出来的,想要知道怎么弄的,完全可以参考如下链接:
http://daiyuwen.freeshell.org/gb/rol/roots_of_lisp.html
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 1 反对 0

使用道具 举报

发表于 2013-5-19 11:33:27 | 显示全部楼层
一个 Common lisp 中关于 Subst
http://clhs.lisp.se/Body/f_substc.htm
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-5-20 14:06:40 | 显示全部楼层
  1. ;;给大家写个Append#函数,理解了这个函数,大家就知道在涉及大量表运算时,
  2. ;; append函数的效率要比cons函数的效率低的原因了!
  3. ;; (append# '(1 2 3 4) '(5)) 经过4次cons运算得到 '(1 2 3 4 5)
  4. (defun append# (a b)
  5.   (cond (a (cons (car a) (append# (cdr a) b)))
  6.         (t b)
  7.         )
  8.   )
  9. ;;测试 用 append函数组表
  10. (defun c:tt ()
  11.   (setq i 0 l nil)
  12.   (setq StartTime (car (_VL-TIMES)))
  13.   (repeat 10000
  14.     (setq l (append l (list (setq i (1+ i)))))
  15.     )
  16.   (princ (strcat "\n  用时  " (rtos (* 0.001 (- (car (_VL-TIMES)) StartTime)) 2 4) "  秒 "))
  17.   (princ)
  18.   )
  19. ;|命令: tt
  20.   用时  6.438  秒
  21.   |;
  22. ;;用cons函数组表
  23. (defun c:tt1 ()
  24.   (setq i 0 l nil)
  25.   (setq StartTime (car (_VL-TIMES)))
  26.   (repeat 10000
  27.     (setq l (cons (setq i (1+ i)) l))
  28.     )
  29.   (reverse l)
  30.   (princ (strcat "\n  用时  " (rtos (* 0.001 (- (car (_VL-TIMES)) StartTime)) 2 4) "  秒 "))
  31.   (princ)
  32.   )
  33. ;|命令: tt1
  34.   用时  0.031  秒
  35.   |;
  36. ;;用cons函数用时几乎可以忽略,而用Append却用了6秒多,所以在涉及大量Append运算时,我们要尽量想方设法避免!

评分

参与人数 1D豆 +5 收起 理由
eachy + 5 技术引导讨论和指点奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 74个

财富等级: 招财进宝

发表于 2013-5-20 16:19:03 | 显示全部楼层
又够想一阵子了!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-5-20 20:58:25 | 显示全部楼层
Assoc# 来了
  1. (defun assoc# (x y)
  2.   (cond
  3.     ((= y nil) nil)
  4.     ((= (caar y) x) (car y))
  5.     (t
  6.      (assoc# x (cdr y))
  7.     )
  8.   )
  9. )

点评

((= (caar y) x) (car y))应该替换为((= (caar y) x) (cadar y))  发表于 2013-5-20 23:24

评分

参与人数 1D豆 +5 收起 理由
牢固 + 5 技术引导讨论和指点奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 207个

财富等级: 日进斗金

发表于 2013-5-20 22:04:04 | 显示全部楼层
本帖最后由 xshrimp 于 2013-5-20 22:24 编辑

  1. (defun Pair(x y)
  2.   (cond (x (cons (list (car x)(car y)) (Pair (cdr x) (cdr y))))
  3.         (t nil)
  4.   )
  5. )

(pair '(x y z) '(a b c))   
==>((x a) (y b) (z c))

表长度不一致时,按照最短的表返回
  1. (defun Pair(x y)
  2.   (if(and x y) (cons (cons(car x)(car y)) (Pair (cdr x) (cdr y))))
  3. )

点评

x 换成 (and x y) 就对了  发表于 2013-5-20 22:55

评分

参与人数 1D豆 +5 收起 理由
牢固 + 5 技术引导讨论和指点奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2013-5-20 22:10:41 | 显示全部楼层
xshrimp 发表于 2013-5-20 22:04
(pair '(x y z) '(a b c))   
==>((x a) (y b) (z c))

如果表一长一短呢?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 207个

财富等级: 日进斗金

发表于 2013-5-20 22:16:38 | 显示全部楼层
本帖最后由 xshrimp 于 2013-5-20 22:20 编辑
eachy 发表于 2013-5-20 22:10
如果表一长一短呢?

按照最短表的长度决定.mapcar就是
  1. (defun Pair(x y)
  2. (mapcar '(lambda(a b) (list a b)) x y)
  3. )

(pair '(1 2 3) '(a b c))
=>((1 A) (2 B) (3 C))

(pair '(1 2 )  '(a b c))
=>((1 A) (2 B))

(pair '(1 2 3) '(a b))
=>((1 A) (2 B))


论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2013-5-20 23:02:21 | 显示全部楼层

和LZ的要求还有差距
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 207个

财富等级: 日进斗金

发表于 2013-5-20 23:13:19 | 显示全部楼层
我来个subst#

  1. (defun subst#(n o lst / x)
  2.   (if lst
  3.     (cons      
  4.       (cond
  5.         ((atom (setq x (car lst)))         
  6.          (if (= x o) n x)
  7.         )
  8.         (T (subst# n o x))
  9.       )     
  10.       (subst# n o (cdr lst))
  11.       )   
  12.     )
  13.   )
例如:
(subst# 'm 'b '(a b (a b c) d))
==> (a m (a m c) d)

(subst# 2 3  '( 1 (2 ( 3 2 5) 6 3 7) 2 3))
==> (1 (2 (2 2 5) 6 2 7) 2 2)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2013-5-20 23:27:22 | 显示全部楼层
xshrimp 发表于 2013-5-20 23:13
我来个subst#例如:
(subst# 'm 'b '(a b (a b c) d))
==> (a m (a m c) d)

是这样写的
http://www.xdcad.net/forum/forum ... 196&pid=3454915
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 207个

财富等级: 日进斗金

发表于 2013-5-20 23:46:39 | 显示全部楼层
把上面链接的
ll_j发布这个subst#贴上来
  1. (defun subst# (x y z)
  2.   (cond
  3.     ((atom z)
  4.      (cond ((eq z y) x)
  5.      (t z)
  6.      )
  7.     )
  8.     (t
  9.      (cons (subst# x y (car z))
  10.      (subst# x y (cdr z))
  11.      )
  12.     )
  13.   )
  14. )

评分

参与人数 1D豆 +5 收起 理由
wowan1314 + 5 NB

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 604个

财富等级: 财运亨通

发表于 2013-5-21 17:57:34 | 显示全部楼层
本帖最后由 /db_自贡黄明儒_ 于 2013-5-21 18:00 编辑

高飞的这个看起来简单,其实难呀,
(defun append# (x y)
  (cond ((car x) (cons (car x) (append# (cdr x) y)))
((car y) (cons (car y) (append# (cdr y) x)))
  )
)
我的这个满足高飞的要求,看看行不?



论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-5-21 18:31:45 来自手机 | 显示全部楼层
/db_自贡黄明儒_ 发表于 2013-5-21 17:57
高飞的这个看起来简单,其实难呀,
(defun append# (x y)
  (cond ((car x) (cons (car x) (append# (cdr ...

第二个条件的写法多余,直接 y就ok了!看楼上我的回复!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-23 15:08 , Processed in 0.485487 second(s), 67 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表