Prolog - 替换子项目

时间:2016-05-16 18:20:10

标签: 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.

任何指针都会非常感激。请注意,对于考试,我们不能使用外部模块。

感谢您的时间。

1 个答案:

答案 0 :(得分:2)

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

结果:不多。

例如:

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)).