cal*_*leb 4 prolog wumpus-world
我正在使用SWI-Prolog创建一个Wumpus World项目.我应该从.txt文件中读取金币,凹坑和Wumpus的位置,如下所示:
GOLD 3 2
WUMPUS 3 3
PIT 2 1
PIT 3 4
Run Code Online (Sandbox Code Playgroud)
在单词标识对象的情况下,第一个数字标识对象的x位置,第二个数字标识对象的y位置.我知道如何打开文件并从中读取,我只是不知道如何告诉我的程序GOLD 3 2意味着黄金需要位于(3,2).
我想为现有的解决方案添加基于DCG的解决方案.
使用DCG执行此任务有几个主要优点:
以下代码假定设置:
:- set_prolog_flag(double_quotes, chars).
我建议使用此设置,因为它使DCG更易读.
token//1我们首先简单定义一个令牌的含义:
token(T) -->
alnum(L),
token_(Ls),
!, % single solution: longest match
{ atom_chars(T, [L|Ls]) }.
alnum(A) --> [A], { char_type(A, alnum) }.
token_([L|Ls]) --> alnum(L), token_(Ls).
token_([]) --> [].
这里有一些例子:
?- phrase(token(T), "GOLD"). T = 'GOLD'. ?- phrase(token(T), "2"). T = '2'. ?- phrase(token(T), "GOLD 2"). false.
最后一个示例清楚地表明,空格不能是令牌的一部分.
我们将以下序列视为空白:
spaces --> [].
spaces --> space, spaces.
space --> [S], { char_type(S, space) }.
因此,由空格分隔的一系列令牌是:
tokens([]) --> []. tokens([T|Ts]) --> token(T), spaces, tokens(Ts).
我们现在可以透明地将这个DCG应用于文件,使用Ulrich Neumerkel的远见卓识library(pio):
这是wumpus.data:
$ cat wumpus.data GOLD 3 2 WUMPUS 3 3 PIT 2 1 PIT 3 4
使用phrase_from_file/2将DCG应用于文件,我们得到:
?- phrase_from_file(tokens(Ts), 'wumpus.data'). Ts = ['GOLD', '3', '2', 'WUMPUS', '3', '3', 'PIT', '2', '1', 'PIT', '3', '4'] .
从这样的令牌列表中,很容易得到必要的数据,例如再次使用DCG:
data([]) --> [].
data([D|Ds]) --> data_(D), data(Ds).
data_(gold(X,Y)) --> ['GOLD'], coords(X, Y).
data_(wumpus(X,Y)) --> ['WUMPUS'], coords(X, Y).
data_(pit(X,Y)) --> ['PIT'], coords(X, Y).
coords(X, Y) --> atom_number(X), atom_number(Y).
atom_number(N) --> [A], { atom_number(A, N) }.
我们可以将这些DCG一起用于:
示例查询:
?- phrase_from_file(tokens(Ts), 'wumpus.data'), phrase(data(Ds), Ts). Ts = ['GOLD', '3', '2', 'WUMPUS', '3', '3', 'PIT', '2', '1'|...], Ds = [gold(3, 2), wumpus(3, 3), pit(2, 1), pit(3, 4)] .
有关此通用机制的更多信息,请参阅dcg.
1请注意,SWI-Prolog附带过时版本library(pio),但不适用于double_quotes设置为 chars.如果您想使用SWI-Prolog试用,请直接使用Ulrich提供的版本.
| 归档时间: |
|
| 查看次数: |
579 次 |
| 最近记录: |