如果存在不能满足所有参数的规则,是否有一种标准的方法来仅对某些参数进行部分匹配?
例如,以下查询找不到解决方案:
?- 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).
答案 0 :(得分:3)
首先,对编程风格进行评论。使用析取符(;/2
)时,请始终将其括在括号之间,并避免在行尾写入;
。就您而言:
query_best_effort(A, B, C) :-
( query_chain3(A, B, C)
; query_chain2(A, B)
; query_chain1(A)
).
此推荐样式有助于提高代码的可读性。
您还可以避免使用否定(\+/1
),而应使用在几个Prolog系统(一些系统,例如SICStus Prolog)中实现的*->/2
soft-cut 控制结构,将其实现为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/3
谓词query_chain2/2
和| ?- query_best_effort(A, B, C).
A = alfa
B = bravo
yes
目标的解决方案,我认为您的意图是使用析取和否定?
通话示例:
*->/2
但是请注意,import csv
with open("thetext.txt") as txt, open('theoutput.csv', 'a') as csvfile:
writer = csv.writer(csvfile, delimiter=';')
writer.writerow(('ID', 'Reporttext'))
id = 1
for line in txt:
words = line.strip().split("@@@")
for word in words:
writer.writerow((id, word.strip()))
id += 1
就像否定一样,是一种非逻辑控制结构。