2016-12-13 85 views
0

以下Prolog打印done的目標爲test1test2,但不是test3。我的理解是這個代碼中的match_test2match_test3應該是等效的。如何通過斷言創建DCG規則?如何在Prolog中聲明DCG規則?

setup(['t','e','s','t']). 

match_test1 --> ['t','e','s','t']. 
test1 :- 
    setup(C), 
    phrase(match_test1,C), 
    write("done"). 

test2 :- 
    setup(C), 
    assert(match_test2(['t','e','s','t'],[])), 
    phrase(match_test2,C), 
    write("done"). 

test3 :- 
    setup(C), 
    assert(match_test3 --> ['t','e','s','t']), 
    phrase(match_test3,C), 
    write("done"). 

使用SWI-Prolog的版本7.2.3 x86_64的-darwin14.3.0,運行如swipl -l bug.pl -t test1(或test2test3

回答

2

使用expand_term/2翻譯的DCG到正規的條款第一:

 
?- expand_term(match_test1 --> [t,e,s,t], Clause). 
Clause = (match_test1([t, e, s, t|_1498], _1498):-true). 

然後在Clause上照常使用assertz/1,即assertz(Clause)

請注意,您可以直接寫下原子,即代替'e',只需編寫  e即可。

此外,可以考慮通過將指令設置double_quoteschars

 
:- set_prolog_flag(double_quotes, chars). 

現在你可以寫,很方便:

 
?- T = "test". 
T = [t, e, s, t]. 

這個語法是非常好的,讓DCG中一很容易 調試和使用。