sicp每日一题[2.73]

最近状态不太好,再加上2.73前面的内容有点多,学的有点吃力,所以昨天就没做。。

Exercise 2.73

Section 2.3.2 described a program that performs symbolic differentiation:

(define (deriv exp var)(cond ((number? exp) 0)((variable? exp)(if (same-variable? exp var) 1 0))((sum? exp)(make-sum (deriv (addend exp) var)(deriv (augend exp) var)))((product? exp)(make-sum (make-product(multiplier exp)(deriv (multiplicand exp) var))(make-product(deriv (multiplier exp) var)(multiplicand exp))))⟨more rules can be added here⟩(else (error "unknown expression type: DERIV" exp))))

We can regard this program as performing a dispatch on the type of the expression to be differentiated. In this situation the “type tag” of the datum is the algebraic operator symbol (such as +) and the operation being performed is deriv. We can transform this program into data-directed style by rewriting the basic derivative procedure as

(define (deriv exp var)(cond ((number? exp) 0)((variable? exp) (if (same-variable? exp var) 1 0))(else ((get 'deriv (operator exp))(operands exp) var))))(define (operator exp) (car exp))
(define (operands exp) (cdr exp))

a. Explain what was done above. Why can’t we assimilate the predicates number? and variable? into the data-directed dispatch?
b. Write the procedures for derivatives of sums and products, and the auxiliary code required to install them in the table used by the program above.
c. Choose any additional differentiation rule that you like, such as the one for exponents (Exercise 2.56), and install it in this data-directed system.
d. In this simple algebraic manipulator the type of an expression is the algebraic operator that binds it together. Suppose, however, we indexed the procedures in the opposite way, so that the dispatch line in deriv looked like

((get (operator exp) 'deriv) (operands exp) var)

What corresponding changes to the derivative system are required?


首先做这道题之前要先把 put 和 get 函数给加进来

(define *operation-table* (make-hash))(define (put op-type op-name procedure)(hash-set! *operation-table* (list op-type op-name) procedure))(define (get op-type op-name)(hash-ref *operation-table* (list op-type op-name) #f))

a. 上面的程序就是从 data-directed dispatch 表里取出一个操作为 deriv,类型为 (operator exp) 的过程,并把表达式和变量传给这个提取出的过程。不把 number? 和 variable? 放到 data-directed dispatch 表的原因是因为它们两个只需要一个参数,而这个程序会给取出的过程2个参数。我看到别人的答案基本都是说这两个过程没有标签,而且不需要加标签,所以不能放入 data-directed dispatch 表,但是题目问的是 why can’t,它们的解释不是 can’t 而是 needn’t,不知道我的理解对不对。
b&c. 这两问情况一样,难度也不大,参考 2.56 的练习,只需要修改一下取操作数的逻辑就可以了,因为 “+, *, **” 本身已经作为区分采用哪个过程的符号,所以取操作数不是从第二个取,而是第一个,其他地方就照搬过来就可以了。

(define (install-deriv-package);; internal procedures;; sum(define (make-sum a1 a2)(cond ((=number? a1 0) a2)((=number? a2 0) a1)((and (number? a1) (number? a2)) (+ a1 a2))(else (list '+ a1 a2))))(define (sum? x) (and (pair? x) (eq? (car x) '+)))(define (addend s) (car s))(define (augend s) (cadr s))(define (sum-deriv expr var) (make-sum (deriv (addend expr) var) (deriv (augend expr) var))) ;; product(define (make-product m1 m2)(cond ((or (=number? m1 0) (=number? m2 0)) 0)((=number? m1 1) m2)((=number? m2 1) m1)((and (number? m1) (number? m2)) (* m1 m2))(else (list '* m1 m2))))(define (product? x) (and (pair? x) (eq? (car x) '*)))(define (multiplier p) (car p))(define (multiplicand p) (cadr p))(define (product-deriv expr var) (make-sum (make-product (deriv (multiplier expr) var) (multiplicand expr))(make-product (multiplier expr)(deriv (multiplicand expr) var))));; exponentiate(define (make-exponentiation base exponent)(cond ((=number? base 0) 0)((=number? base 1) 1)((and (number? base) (=number? exponent 0)) 1)((and (number? base) (=number? exponent 1)) base)((and (number? base) (number? exponent)) (* base (make-exponentiation base (- exponent 1))))(else (list '** base exponent))))(define (base e) (car e))(define (exponent e) (cadr e))(define (exponentation-deriv expr var) (make-product (exponent expr) (make-product  (make-exponentiation (base expr) (make-sum (exponent expr) -1)) (deriv (base expr) var))));; interface to the rest of the system(put 'deriv '+ sum-deriv)(put 'deriv '* product-deriv)(put 'deriv '** exponentation-deriv)'done)(install-deriv-package)(deriv '(+ x x x) 'x) 
(deriv '(* x x x) 'x) 
(deriv '(+ x (* x  (+ x (+ y 2)))) 'x) 
(deriv '(+ x (* 3 (+ x (+ y 2)))) 'x)
(deriv '(** x 3) 'x) ; 结果如下
'done
2
'(+ x x)
'(+ 1 (+ (+ x (+ y 2)) x))
4
'(* 3 (** x 2))

d. 这样的话,只要在使用 put 函数的时候也先传类型,再传操作就可以了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/10148.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【MyBatis源码】SQL 语句构建器AbstractSQL

文章目录 介绍org.apache.ibatis.jdbc.SQLSQL类使用示例SelectProvider搭配动态SQLAbstractSQL类源码分析 介绍 当我们需要使用Statement对象执行SQL时,SQL语句会嵌入Java代码中。SQL语句比较复杂时,我们可能会在代码中对SQL语句进行拼接,查…

Vue2进阶

1.el安装 官网地址 Element - The worlds most popular Vue UI frameworkElement,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.eleme.cn/#/zh-CN 安装 npm install element-ui -S 引入组件(在 main.js&#xf…

案例:三次锁定(下)

第二步: 在 Form1.cs 中完成以下代码 using Dome16_三次锁定.service; using Dome16_三次锁定.service.serviceimpl; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using Sys…

前端学习笔记—Vue3特性

一、 Vue3与Vite构建工具简介 image.png image.png image.png image.png Vite构建工具(其他的打包工具有webpack,grunt,gulp) image.png image.png 构建 二、创建Vue3项目 vite在TypeScript结合使用上,直接开箱即用&am…

iOS 去掉URL里面的百分号符号

遇到这个一段字符串 “publicId2030095197043302&publicBizTypeCONTENT_USER&chInfoch_life__chsub_Ndiscovery.featured&logoUrlhttps%3A%2F%2Fmdn.alipayobjects.com%2Fopen_content%2Fafts%2Fimg%2FA*_SUKQodfigcAAAAAAAAAAAAAfVx1AQ%2Foriginal&publicName…

node.js安装配置(Windows)

1、下载 CNPM Binaries Mirror 2、安装 3、验证 win R 进入cmd 4、配置环境变量 4.1、创建两个文件夹 4.2、安装目录进入cmd(配置全局属性) 配置两个命令: npm config set prefix "D:\liyunqing\nodejs\node_global"npm config set cache "D:\l…

jdbc中预防SQL攻击

目录 展示SQL攻击 举一个出现sql 攻击的例子 SQL攻击的原因 分析原因 阻止SQL攻击 PreparedStatement的含义 使用PreparedStatement的原因 步骤如下 注意 总结 展示SQL攻击 举一个出现sql 攻击的例子 假设我们在做登录业务时,思路是这样的: 首…

30.1 时序数据库TSDB的典型特点

本节重点介绍 : db-ranking网站对db进行排名时序数据特点时序数据库特点时序数据库遇到的挑战开源时间序列数据库 db-ranking 一个神奇的网站 https://db-engines.com/en/ranking 时序数据ranking https://db-engines.com/en/ranking/timeseriesdbms 排名方法 https://db-en…

14:00面试,14:06就出来了,问的问题过于变态了。。。

我从一家小公司转投到另一家公司,期待着新的工作环境和机会。然而,新公司的加班文化让我有些始料未及。虽然薪资相对较高,但长时间的工作和缺乏休息使我身心俱疲。 就在我逐渐适应这种高强度的工作节奏时,公司突然宣布了一则令人…

架构师之路-学渣到学霸历程-49

实现不同终端的跳转实验 今天分享一下: nginx的跳转:主要看你的访问是手机还是网页;于是就有这个跳转的功能; 1、基础的环境部署 安装好nginx(这里最好的就是干净的环境)创建两个server;用于…

RK3568笔记1:BootRom

BootRom是瑞芯微公司在生产的CPU时,存储在内部flash中的一段固件代码,用于初始化硬件和启动系统。 RK3568 处理器也具备 BootROM。这是存储在处理器内部的只读存储器 (ROM) 中的一段代码,通常是不可修改的,其主要功能是在设备加电…

DataWind将字符串数组拆出多行的方法

摘要: 可视化建模中先将字符串split为array再用explode(array)即可 可视化建模 进入“可视化建模”页面 1.1 新建任务 如果团队内没有可视化建模任务。请点击“新建任务”,输入名称并确定。 1.2 建立数据连接 在左边栏中选择“数据连接”&#xff0c…

2024年【电工(中级)】考试及电工(中级)考试报名

题库来源:安全生产模拟考试一点通公众号小程序 电工(中级)考试参考答案及电工(中级)考试试题解析是安全生产模拟考试一点通题库老师及电工(中级)操作证已考过的学员汇总,相对有效帮…

【韩老师零基础30天学会Java】02章

sublime Text中本身没有GBK编码,需要安装 要在sublime Text中设置编码为GBK,请按照以下步骤操作 打开Sublime Text编辑器,点击菜单栏中的“Preferences”(首选项)选项,找打Package Control选项。点击Package Control,随后搜索Inst…

Pytorch实现运动鞋识别

Pytorch实现运动鞋识别 🍨 本文为🔗365天深度学习训练营 中的学习记录博客 🍖 原作者:K同学啊 电脑系统:Windows11 显卡型号:NVIDIA Quadro P620 语言环境:python 3.9.7 编译器:j…

老年人跌倒智能检测系统

项目源码获取方式见文章末尾! 600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

Spring Boot原理全解析:如何让开发更轻松高效(二)-起步依赖、自动装配

通过这篇博客,读者将能够掌握 Spring Boot 中的配置优先级和 Bean 管理的核心原理,为开发更加高效、可维护的 Spring Boot 应用打下坚实的基础。 目录 前言 起步依赖 自动配置 概述 常见方案 概述 方案一 方案二 总结 前言 通过这篇博客&#xf…

测试实项中的偶必现难测bug--短信触发H5拒绝行为

问题描述: 企业邀请其他人加入团队,发送邀请短信给对方,对方通过短信链接跳转到H5页面,输入手机后,点击发送验证码,前提是短信通知验证弹窗需要打开,收到短信验证码后,点击一键代入,会触发拒绝加入行为。 需求: 由于我们的邀请链接是一次性的,一旦有用户确认加入或…

PVE纵览-PVE与VM:谁才是你的最佳虚拟化选择?

PVE纵览-PVE与VM:谁才是你的最佳虚拟化选择? 文章目录 PVE纵览-PVE与VM:谁才是你的最佳虚拟化选择?摘要1 不同虚拟化平台的基础2 平台特性与功能3 性能与可靠性4 成本与经济性5 应用场景比较6 用户体验与支持7 结论与建议 关键字&…

陪诊问诊APP开发实战:基于互联网医院系统源码的搭建详解

时下,开发一款功能全面、用户体验良好的陪诊问诊APP成为了医疗行业的一大热点。本文将结合互联网医院系统源码,详细解析陪诊问诊APP的开发过程,为开发者提供实用的开发方案与技术指导。 一、陪诊问诊APP的背景与功能需求 陪诊问诊APP核心目…