Prolog中是否可以进行自适应解析?

And*_*een 7 machine-learning prolog dcg

我试图在Prolog中编写一个自适应解析器:换句话说,一个可以在运行时修改自己的解析规则的解析器.

为了做到这一点,我需要在运行时生成新的谓词,但我不确定这是否可行.是否可以编写一个带有这样一个列表的谓词:

generate_dcg_rule([A," is greater than ",B]).
Run Code Online (Sandbox Code Playgroud)

...然后生成一个像这样的新谓词?

expr(A," is greater than ",B) -->
    symbol(A)," is greater than ",symbol(B).
Run Code Online (Sandbox Code Playgroud)

mat*_*mat 5

是的,这很容易实现.

Prolog是一种非常动态的语言,例如,您可以在运行时断言任意子句assertz/1.

您可以使用通常用于执行此操作的Prolog术语扩展机制将DCG规则扩展为普通的Prolog规则.

例如,使用expand_term/2:

?- expand_term((expr(A," is greater than ",B) -->
    symbol(A)," is greater than ",symbol(B)), Clause).
Clause =  (expr(A, [' ', i, s, ' ', g, r, e|...], B, _G242, _G253):-symbol(A, _G242, _G264), _G264=[' ', i, s, ' ', g|...], symbol(B, _G275, _G253)).

你可以断言这样的条款assertz/1:

?- expand_term((Head --> Body), Clause), assertz(Clause).

请注意,我在此示例中使用double_quotesset chars,即使用:

:- set_prolog_flag(double_quotes, chars).

在您的源文件中.无论如何,这是一个好主意.

另请注意,我假设您已经找到了将generate_dcg_rule/1示例中给出的列表转换为实际DCG的方法.对于这个翻译,我宁愿推荐一个类似谓词list_dcg/2描述这些列表和DCG规则之间关系的谓词.优点很明显:例如,您可以交互式地测试这种关系以及测试用例等.对于您的具体示例,定义此关系的一个子句可以类似于:

list_dcg([A,Ls,B], DCG) :-
        Ls = "is greater than ",
        DCG = (expr(A, Ls, B) --> symbol(A), Ls, symbol(B)).

我将此概括为您的其他用例作为练习.总的来说,动态断言这些子句的一种方法是:

?- list_dcg(List, DCG), expand_term(DCG, Clause), assertz(Clause).

请注意我们如何从 这些例子中受益于Prolog的同质性:Prolog规则 DCG规则具有Prolog 术语的自然表示  ,我们可以简单地将它们写下来并像在目标内的任何其他术语一样推理它们.