recursion - Prolog - 替换子项

标签 recursion prolog universal

我正在做一些过去的试卷来练习考试,我遇到了一个不太确定如何解决的问题:

enter image description here

我知道我必须使用“univ”函数将术语分解为列表,然后递归该列表并检查列表中的任何元素是否等于我们要替换的术语。然而,当列表包含另一个我们必须进一步分解的复杂术语时,我对双重递归有点迷失。到目前为止我的尝试如下:

complexTerm(X) :- nonvar(X), functor(X, _, A), A > 0.

replace(Term, Subterm, Subterm1, Term1) :-
    Term =.. [H|T],
    replaceSub([H|T], Subterm, Subterm1, Term1)

replaceSub([], Subterm, Subterm1, Term1).
replaceSub([H], Subterm, Subterm1, Term1) :- 
    atomic(X),
    H == Subterm, 
    H = Subterm1.
replaceSub([H], Subterm, Subterm1, Term1) :-
    complexTerm(H),
    replace(H, Subterm, Subterm1, Term1).
replaceSub([H|T]) :- % not sure where to continue with this.

任何指示将不胜感激。请注意,对于考试,我们不能使用外部模块。

感谢您的宝贵时间。

最佳答案

此类任务的关键是识别您实际上需要区分哪些情况

事实证明:并不多。

例如:

replace(Subterm0, Subterm, Term0, Term) :-
        (   Term0 == Subterm0 -> Term = Subterm
        ;   var(Term0) -> Term = Term0
        ;   Term0 =.. [F|Args0],
            maplist(replace(Subterm0,Subterm), Args0, Args),
            Term =.. [F|Args]
        ).

我稍微自由地使用了使 maplist/3 适用的参数顺序。

引用 Prolog 标准:

8.5.3 (=..)/2 - univ

8.5.3.1 Description

'=..'(Term, List) is true iff:

  - Term is an atomic term and List is the list whose
  only element is Term, or
  ...

因此,在这种情况下,可以统一处理原子术语和复杂术语!没有理由区分原子术语和复杂术语,也没有任何理由以任何方式特殊对待列表。

示例:

?- replace(1, 2, f(a,[[b]],g(1),X,h(z,1)), T).
T = f(a, [[b]], g(2), X, h(z, 2)).

关于recursion - Prolog - 替换子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37260614/

相关文章:

c++ - 为什么我的节点在设置为新节点后被设置为 nullptr?

prolog - 首次解决斐波那契货币对后防止回溯

ios - Xcode在通用应用程序的部署信息部分没有选择设备

ios - 触摸功能在 iOS 中无法正常工作

sql-server-2008 - 在将所有函数放入 SQL Server 之前,如何从 CLR 程序集中删除所有函数?

algorithm - 投资者和资金池 - 回溯

java - 在我的案例中,我可以在不循环遍历所有前面元素的情况下计算一个元素吗(参见问题正文)?

python - 为什么返回自身的函数在 python 3 中最大递归

prolog - swi-prolog 中 -> 的含义

prolog - 尝试编写树高谓词 - 我是否需要 Peano 风格的自然数?