【问题标题】:Prolog - replacing subtermsProlog - 替换子项
【发布时间】:2016-09-12 15:18:59
【问题描述】:

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

我知道我必须使用“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 可以简单地检查所有术语类型并通过递归来处理复杂的术语。请注意您没有 =.. 案例处理列表案例。
  • @AlanBaljeu 对不起,我的意思是双重递归和递归自身。这是我不确定的步骤。任何指针将不胜感激。

标签: recursion prolog universal


【解决方案1】:

这些任务的关键是识别你真正需要区分的情况

事实证明:并不多。

例如:

替换(Subterm0,Subterm,Term0,Term):- ( Term0 == Subterm0 -> Term = Subterm ; var(Term0)-> Term = Term0 ; Term0 =.. [F|Args0], 地图列表(替换(Subterm0,Subterm),Args0,Args), 项 =.. [F|Args] )。

我冒昧地使用了使maplist/3 适用的参数顺序。

引用 Prolog 标准:

8.5.3 (=..)/2 - 大学 8.5.3.1 说明 '=..'(Term, List) 为真当且仅当: - 术语是原子术语,列表是其列表 唯一的元素是 Term,或者 ...

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

例子:

?- 替换(1, 2, f(a,[[b]],g(1),X,h(z,1)), T)。 T = f(a, [[b]], g(2), X, h(z, 2))。

【讨论】:

  • 在某些情况下,此谓词不会将输入模式替换为输出模式。 replace(A+B,A-B,(2+3),Result)Result2+3 统一起来,而不是 2-3
  • 在这种情况下似乎可以正常工作,因为A+B 不是2+3 的子项,是吗?
  • replace(2, 1, T0, f(a,[[b]],g(1),X,h(z,1))). 只产生一个答案,这是图片中的任务描述要求产生的几个答案中的第一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-13
  • 2011-08-16
  • 1970-01-01
  • 2013-03-21
相关资源
最近更新 更多