我想构建一种机制,根据在 prolog 中导入的 txt 文件构造不同的事实。我已经找到了一些示例,它们直接断言从文件中读取的行,但是我必须在断言发生之前转换数据。
举个例子:
man = {m1, m2}.
m1: w1 > w2.
应该读作:
man(m1).
man(m2).
prefer(m1, w1, 1).
prefer(m1, w2, 2).
是否可以根据输入的符号构造这些事实?
我想构建一种机制,根据在 prolog 中导入的 txt 文件构造不同的事实。我已经找到了一些示例,它们直接断言从文件中读取的行,但是我必须在断言发生之前转换数据。
举个例子:
man = {m1, m2}.
m1: w1 > w2.
应该读作:
man(m1).
man(m2).
prefer(m1, w1, 1).
prefer(m1, w2, 2).
是否可以根据输入的符号构造这些事实?
是的 - 你需要做你会用任何其他语言做的事情。
打开并读取文件,解析内容,然后转换为您可以断言的术语。
幸运的是,您在 prolog 中,因此“解析内容”是语言在早餐时执行的一项任务。
事实证明,我一直在写一个关于如何完成这个确切任务的教程。还没完,网上有
http://www.pathwayslms.com/swipltuts/dcg/
如果您的文件很大,请使用教程中描述的方法来阅读它们。否则,只需将文件带入“代码”样式字符串并继续生活。
由于示例中提供的数据是有效的 Prolog 语法这一事实,这段代码就可以了
load_file_data(File) :-
open(File, read, Stream),
repeat,
read(Stream, Term),
( Term = end_of_file
-> true
; process(Term),
fail
),
close(Stream).
process(X = {L}) :-
forall(arg(_, L, A), (F =.. [X, A], assert(F))).
process(X : A > B) :-
assert(prefer(X, A, 1)),
assert(prefer(X, B, 2)).
请注意,运算符 in 的优先级m1: w1 > w2
不是我们所期望的,但它仍然有效,这要归功于完整的模式匹配。利用
?- write_canonical(m1 : w1 > w2).
>(:(m1,w1),w2)
不确定时检查优先级。
您可以通过将 DCG 包含在 {} 中来执行任何“正常”序言
some_nonterminal --> "fridge", blanks, [X], { % 你可以在这里放任何普通的 Prolog 代码 assert(fridge_named(X)) }。
这寻找一个像
冰箱 G
并在数据库中声明冰箱命名(0x47)(Ascii G 为 0x47)