gpt4 book ai didi

Prolog 部分匹配

转载 作者:行者123 更新时间:2023-12-05 03:02:11 25 4
gpt4 key购买 nike

如果有一条规则不能满足所有参数,是否有一种标准方法可以仅使用部分参数进行部分匹配?

例如下面的查询找不到解决办法:

?- query(A, B, C).
false.

但如果我们不尝试在 C 上统一,则可以找到解决方案:

?- query_best_effort(A, B, C).
A = alfa,
B = bravo ;

我有以下实现此功能的代码。但是有没有更多的 Prolog 方式来做到这一点?

fact1(alfa).
fact2(bravo).
fact3(charlie).

rule1(A) :-
fact1(A).

rule2(B) :-
fact2(B).

rule3(C) :-
fact3(C),
C \== charlie.

query(A, B, C) :-
rule1(A),
rule2(B),
rule3(C).

query_best_effort(A, B, C) :-
query_chain3(A, B, C);
query_chain2(A, B);
query_chain1(A).

query_chain3(A, B, C) :-
query(A, B, C).

query_chain2(A, B) :-
\+query_chain3(A, B, _),
rule1(A),
rule2(B).

query_chain1(A) :-
\+query_chain2(A, _),
rule1(A).

最佳答案

首先,对编程风格的评论。使用析取符 (;/2) 时,始终将它们括在括号中并避免在行尾编写 ;。在你的情况下:

query_best_effort(A, B, C) :-
( query_chain3(A, B, C)
; query_chain2(A, B)
; query_chain1(A)
).

这种推荐的风格有助于提高代码的可读性。

您还可以通过使用 *->/2 soft-cut 控制结构来避免使用否定 (\+/1)在多个 Prolog 系统中实现(一些系统,例如 SICStus Prolog,将其实现为 if/3 内置谓词):

query_best_effort(A, B, C) :-
( query_chain3(A, B, C) *->
true
; query_chain2(A, B) *->
true
; query_chain1(A)
).

query_chain3(A, B, C) :-
query(A, B, C).

query_chain2(A, B) :-
rule1(A),
rule2(B).

query_chain1(A) :-
rule1(A).

*->/2 控制结构与标准的->/2 控制结构不同,它允许回溯到条件中。当调用 query_best_effort/3 谓词时,query_chain2/2 谓词只有在 query_chain3/3 目标没有解时才会被调用,并且query_chain1/1 谓词只有在没有针对 query_chain3/3query_chain2/2 目标的解决方案时才会被调用,我假设是你使用析取和否定的意图是什么?

示例调用:

| ?- query_best_effort(A, B, C).

A = alfa
B = bravo
yes

但是请注意,*->/2 与否定一样,是一个非逻辑控制结构。

关于Prolog 部分匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55163483/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com