recursion - 使用 Prolog 中其他谓词返回的值递归构建列表

标签 recursion prolog

免责声明:这是一项学校作业。

Prolog 新手,对基础知识有很好的了解。赋值就是对多项式求微分。这部分不是问题。我设计了一种可行的算法,并在 Prolog 中实现了它,令我满意。此时,调用 diff_term 谓词每次都会产生正确微分的多项式项。

但是,当我将完整的多项式传递给 diff_poly 谓词(其工作是解析术语、传递它们以进行微分)并将它们重新收集到列表中以返回给用户时,事情就崩溃了。我的问题是将返回的多项式项(列表)递归地添加到全微分多项式(另一个列表)中。我查阅了许多相关的 Stackoverflow 问题,发现这个特别有用:

Prolog - recursive list building

我仔细阅读了它并重新创建了相同的程序以理解它。然而,主要的区别在于,在我的情况下,我添加到列表中的值是由其他谓词返回的,而不是在构建列表的同一谓词中创建的。

以下代码由我的 diff_poly 组成谓词,然后调用 diff_termdiff_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 微分。到目前为止听起来不错。

子句中的第一个表达式表示, * DiffedTermTermDiffVar 不同。听起来也不错。

下一个注释行表示将 DiffedPolyDiffedTerm 统一。这将不再有意义,因为完全微分多项式通常不仅仅是微分项(当然,除非多项式只有一项)。让我们将其注释掉。

最后,我们有:

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/

相关文章:

list - 使用 prolog 枚举子列表

prolog - 为什么SWI-Prolog只给出一种解决方案?

prolog - Prolog中的[]和[_]是什么意思

.net - 我可以构建尾调用递归优化表达式吗?

python - 生成递归以找到具有最大总和的子列表

java - Java 中本地、开放和递归时的 boolean 值困惑

prolog - 如何正确过滤返回多个重复值的子句?

c++ - 实现递归函数

c# - 需要了解递归在查找单词排列代码示例中如何工作

Prolog 列表中的最大值