Prolog - 替换子项 [英] Prolog - replacing subterms

查看:45
本文介绍了Prolog - 替换子项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

complexTerm(X) :- nonvar(X), functor(X, _, A), A >0.替换(术语,子术语,子术语 1,术语 1):-项 =.. [H|T],replaceSub([H|T], Subterm, Subterm1, Term1)replaceSub([], Subterm, Subterm1, Term1).replaceSub([H], Subterm, Subterm1, Term1) :-原子(X),H == 子项,H = 子项 1.replaceSub([H], Subterm, Subterm1, Term1) :-complexTerm(H),替换(H,Subterm,Subterm1,Term1).replaceSub([H|T]) :- % 不知道从哪里继续.

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

感谢您的时间.

解决方案

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

事实证明:并不多.

例如:

<预>替换(Subterm0,Subterm,Term0,Term):-( Term0 == Subterm0 -> Term = Subterm;var(Term0) ->期限 = 期限 0;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)).

I'm doing some past exam papers for practice for my exam, and I've come across a question that I'm not quite sure how to tackle:

I know I've got to use the "univ" function to break up the term into a list, and then recurse through that list and check if any of the elements in the list equal the term we want to replace. However, I'm a bit lost with double recursing when the list contains another complex term that we have to break down further. My attempt so far is as follows:

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.

Any pointers would be much appreciated. Note that for the exam we can't use external modules.

Thanks for your time.

解决方案

The key to such tasks is to recognize which cases you actually need to distinguish.

As it turns out: Not many.

For example:

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

I have taken the small liberty to use an argument order that makes maplist/3 applicable.

To quote from the Prolog standard:

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

For this reason, atomic and complex terms can be handled uniformly in this case! There is no reason to distinguish between atomic and complex terms, nor is there any reason to treat lists specially in any way.

Example:

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

这篇关于Prolog - 替换子项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆