首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Prolog -简化导数

Prolog -简化导数
EN

Stack Overflow用户
提问于 2015-05-14 04:26:53
回答 1查看 3.4K关注 0票数 7

所以我这个学期刚开始学习Prolog,并且完成了实现一个非常基本的d(function, variable, derivative)的家庭作业,我就是这样做的:

代码语言:javascript
运行
复制
d(X,X,1) :- !.
d(C,X,0) :- atomic(C). %, (C \= X).
d(X**E,X,E*X**(E-1)).
d(U+V,X,A+B) :- d(U,X,A), d(V,X,B).
d(U-V,X,A-B) :- d(U,X,A), d(V,X,B).
d(U*V,X,DU*V+U*DV) :- d(U,X,DU), d(V,X,DV).
d(U/V,X,(DU*V-U*DV)/(V*V)) :- d(U,X,DU), d(V,X,DV).

我知道这并不完整,但它涵盖了练习中所需的所有任务。

但是,?- d((x*x+2*x+3)/(3*x),x,R).会导致

R = ((1*x+x*1+ (0*x+2*1)+0)* (3*x)- (x*x+2*x+3)* (0*x+3*1))/ (3*x* (3*x)).,这看起来一点也不漂亮。不幸的是,is/2不喜欢我的x,因为它不是一个数字...

有没有一个简单的解决方案来实现一个更干净的结果?

EN

Stack Overflow用户

发布于 2015-05-14 12:16:36

获取数字的一种可能性是将变量x的每个实例替换为一个值,访问派生树。您应该编写一个子句来匹配每个二元运算符,或者使用泛型访问,例如

代码语言:javascript
运行
复制
set_vars(E, Vs, Ev) :-
    E =.. [F,L,R],
    set_vars(L, Vs, Lv),
    set_vars(R, Vs, Rv),
    Ev =.. [F,Lv,Rv].
set_vars(V, Vs, N) :- memberchk(V=N, Vs).
set_vars(V, _, V).

这就产生了

代码语言:javascript
运行
复制
?- d((x*x+2*x+3)/(3*x),x,R), set_vars(R,[x=5],E), T is E.
R = ((1*x+x*1+ (0*x+2*1)+0)* (3*x)- (x*x+2*x+3)* (0*x+3*1))/ (3*x* (3*x)),
E = ((1*5+5*1+ (0*5+2*1)+0)* (3*5)- (5*5+2*5+3)* (0*5+3*1))/ (3*5* (3*5)),
T = 0.29333333333333333 

但是,您的第一个子句中有一个错误,一旦更正,将允许直接计算派生表达式:

代码语言:javascript
运行
复制
d(X,V,1) :- X == V, !.
...

现在,我们可以去掉实用程序set_vars/3,所以

代码语言:javascript
运行
复制
?- d((T*T+2*T+3)/(3*T),T,R), T=8, V is R.
T = 8,
R = ((1*8+8*1+ (0*8+2*1)+0)* (3*8)- (8*8+2*8+3)* (0*8+3*1))/ (3*8* (3*8)),
V = 0.3177083333333333.
票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30224582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档