prolog - 非平凡的 Prolog 查找和替换

标签 prolog

因此,我们可以通过执行以下操作轻松地在 Prolog 中找到一个原子并将其替换为另一个原子:

replace([],A,B,[]).
replace([H|T],A,B,[B|Result]) :- 
    H=A, 
    replace(T,A,B,Result),!.
replace([H|T],A,B,[H|Result]) :- 
    replace(T,A,B,Result).

我相信还有其他方法可以做到这一点。

但是,我想在计算逻辑上做一些更复杂的事情。你会如何做类似替换像 conj(x,y) 这样的连词这样的事情在只有 (x,y) 的逻辑语句中?所以它就像 final 和 replace 但不是用原子。所以我们可以有类似 reduce(conj(conj(x,y),z)). 的东西我想减少到 ((x,y),z) .

这是一个只有连词的简单例子,但这就是我想要在连词的情况下发生的事情。如果有人感兴趣,这完全是关于描述性逻辑和画面方法。

当输入实际上不是列表时,我对如何进行查找和替换感到困惑;这是一个结构。我不知道如何在不使用标准的情况下解决这个问题 [H|T]递归和列表技巧。有没有人有任何想法?

非常感谢。

最佳答案

这是通过编写元解释器以一种直接的方式完成的,例如:

replace(V, V) :-
    % pass vars through 
    var(V), !.     
replace(A, A) :- 
    % pass atoms through 
    atomic(A), !.
replace([], []) :- 
    % pass empty lists through
    !.
replace([X|Xs], [Y|Ys]) :-
    % recursively enter non-empty lists
    !, 
    replace(X, Y),
    replace(Xs, Ys).
replace(conj(X,Y), (NX,NY)) :-
    % CUSTOM replacement clause for conj/2
    !, 
    replace(X, NX),
    replace(Y, NY).
replace(T, NT) :-
    % finally, recursively enter any as yet unmatched compound term
    T =.. [F|AL],
    replace(AL, NAL),
    NT =.. [F|NAL].

请注意倒数第二个子句,它用于执行替换 conj/2 的特定情况的替换。连词,,/2 .您可以以与此相同的方式添加尽可能多的其他子句来执行一般的术语替换,因为此处定义的其余部分(replace/2 的所有其他子句)将递归解构任何 PROLOG 术语,因为我们已经涵盖了所有类型;变量、原子和复合术语(包括明确的列表)。

在你的情况下执行这个给我们:
?- replace(conj(conj(x,y),z), NewTerm).
NewTerm = ((x, y), z).

请注意,此定义将正确替换嵌套到另一个术语中任意深度的任何术语。

关于prolog - 非平凡的 Prolog 查找和替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4119023/

相关文章:

http - swi 序言 8.0.2 : gziped http

prolog - check/3 谓词从列表中获取替代元素

command-line - Prolog - 从命令行执行,加载多个文件,执行查询,退出

prolog - 刚开始使用 Prolog,显然对其工作原理有一个根本性的误解,有帮助吗?

prolog - "almost pure"Prolog 有表达力吗?

prolog - Prolog 中的 % 符号是什么意思?

prolog - Prolog 查询中的递归

recursion - 为什么循环引用和递归会使我的程序失败?

Prolog语法问题,否定后的空格

prolog - 使用 Prolog CLPFD 实现 32 位数字的 XOR 功能