免责声明:这是一项学校作业。
Prolog 新手,对基础知识有很好的了解。赋值就是对多项式求微分。这部分不是问题。我设计了一种可行的算法,并在 Prolog 中实现了它,令我满意。此时,调用 diff_term 谓词每次都会产生正确微分的多项式项。
但是,当我将完整的多项式传递给 diff_poly 谓词(其工作是解析术语、传递它们以进行微分)并将它们重新收集到列表中以返回给用户时,事情就崩溃了。我的问题是将返回的多项式项(列表)递归地添加到全微分多项式(另一个列表)中。我查阅了许多相关的 Stackoverflow 问题,发现这个特别有用:
Prolog - recursive list building
我仔细阅读了它并重新创建了相同的程序以理解它。然而,主要的区别在于,在我的情况下,我添加到列表中的值是由其他谓词返回的,而不是在构建列表的同一谓词中创建的。
以下代码由我的 diff_poly
组成谓词,然后调用 diff_term
。 diff_term
然后调用许多其他自制谓词来执行算法;然而,这些都不是问题,而且如上所述,差异化效果很好。您可能仅通过谓词名称就可以理解我的算法方法。
diff_poly
谓词是唯一的diff_poly
存在的;没有基本情况或其他变化,因为我可以假设(根据作业规范)所有输入都将采用一致且有效的格式。然而,还有其他一些diff_term
用于处理术语内容变化的谓词,所有这些都返回正确的术语导数。
如果我打电话diff_poly
照原样,我的返回是“假”。如果我注释掉该谓词的最后一行并取消注释它之前的一行,我就会得到一个返回给我的区分项,这是预期的,因为它们不是递归调用,并证明对 diff_term
的调用/返回有效。
本质上,我只需要一些关于如何构建要返回的列表的指导。我尝试过附加、插入等,但我认为头部匹配策略(在上面的问题中概述)是可行的方法,但我实现了一些错误的东西。任何见解都值得赞赏。
% differentiates a polynomial with respect to given variable
% polynomials are parsed into terms, and terms are passed to diff_term
diff_poly([Term | Rest], DiffVar, DiffedPoly) :-
diff_term(Term, DiffVar, DiffedTerm),
% DiffedPoly = DiffedTerm.
diff_poly(Rest, DiffVar, [DiffedTerm | DiffedPoly]).
% term is a coefficient and at least one var/exp pair in its member variable list
% term includes occurrence of variable to differentiate with respect to
diff_term([Coef | Rest], DiffVar, Return) :-
flatten(Rest, FlatList),
member(DiffVar, FlatList),
index_of(FlatList, DiffVar, Index),
nth1(Index, FlatList, Exp),
Exp > 1, NewCoef is Coef * Exp, NewExp is Exp - 1,
remove_at(FlatList, Index, RemoveList),
insert_at(NewExp, RemoveList, Index, InsertList),
split_varlist(InsertList, DoneList),
Return = [NewCoef | DoneList], !.
最佳答案
假设你的 diff_term
是好的(你可以在 Prolog 提示符下进行模块化测试),让我们看看 diff_poly
:
diff_poly([Term | Rest], DiffVar, DiffedPoly) :-
diff_term(Term, DiffVar, DiffedTerm),
% DiffedPoly = DiffedTerm.
diff_poly(Rest, DiffVar, [DiffedTerm | DiffedPoly]).
该子句表示 DiffedPoly
是多项式 [Term|Rest]
相对于 DiffVar
微分。到目前为止听起来不错。
子句中的第一个表达式表示, * DiffedTerm
是 Term
与 DiffVar
不同。听起来也不错。
下一个注释行表示将 DiffedPoly
与 DiffedTerm
统一。这将不再有意义,因为完全微分多项式通常不仅仅是微分项(当然,除非多项式只有一项)。让我们将其注释掉。
最后,我们有:
diff_poly(Rest, DiffVar, [DiffedTerm | DiffedPoly])
这就是说,对 DiffVar
求导其余多项式(没有第一项)的结果是对 DiffVar
求导的第一项(即 DiffTerm
),然后是完全微分的多项式( DiffedPoly
) )。如果你仔细想想,那就没有道理了。它的写法就好像您更改了 DiffedPoly
的真正含义一样。此查询应表示:完全微分多项式 ( DiffedPoly
) 是初始项 ( DiffedTerm
) 的微分,然后是多项式其余部分的微分( Rest
相对于 DiffVar
的微分)。将最后的描述翻译成 Prolog,那么你就差不多成功了。
几乎...那是因为递归需要有一个基本情况。空多项式会发生什么?对于这种情况,您还需要添加 diff_poly([], <something>, <something>)
。
关于recursion - 使用 Prolog 中其他谓词返回的值递归构建列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21800717/