Prolog 的 DCG 问题

发布于 2024-10-14 21:25:38 字数 1577 浏览 5 评论 0原文

该项目旨在将半自然语言转换为 SQL 表。代码:

label(S) --> label_h(C), {atom_codes(A, C), string_to_atom(S, A)}, !.

label_h([C|D]) --> letter(C), letters_or_digits(D), !.

letters_or_digits([C|D]) --> letter_or_digit(C), letters_or_digits(D), !.
letters_or_digits([C]) --> letter_or_digit(C), !.
letters_or_digits([]) --> "", !.

letter(C) --> [C], {"a"=<C, C=<"z"}, !.
letter(C) --> [C], {"A"=<C, C=<"Z"}, !.
letter_or_digit(C) --> [C], {"a"=<C, C=<"z"}, !.
letter_or_digit(C) --> [C], {"A"=<C, C=<"Z"}, !.
letter_or_digit(C) --> [C], {"0"=<C, C=<"9"}, !.

table("student").

sbvr2sql --> label(Name), " is an integer.", {assert(fields(Name, "INT"))}.
sbvr2sql --> label(Name), " is a string.", {assert(fields(Name, "VARCHAR(64)"))}.

sbvr2sql(Table, Property)  --> label(Table), " has ", label(Property), ".".

这是它如何正常工作的:

?- sbvr2sql("age is an integer.", []).
true 

?- sbvr2sql("firstName is a string.", []).
true.

?- sbvr2sql(T, P, "student has firstName.", []).
T = "student",
P = "firstName".

?- fields(F, T).
F = "age",
T = [73, 78, 84] n
F = "firstName",
T = [86, 65, 82, 67, 72, 65, 82, 40, 54|...].

?- sbvr2sql(T, P, "student has firstName.", []), fields(P, _).
T = "student",
P = "firstName".

但它在这里不起作用:

?- table(T).
T = [115, 116, 117, 100, 101, 110, 116]. % "student"

?- sbvr2sql(T, P, "student has firstName.", []), table(T).
false.

显然它不能将 table("student") 识别为 true。如上所示,它将“学生”识别为标签。什么给?

The project is about translating semi-natural language to SQL tables. The code:

label(S) --> label_h(C), {atom_codes(A, C), string_to_atom(S, A)}, !.

label_h([C|D]) --> letter(C), letters_or_digits(D), !.

letters_or_digits([C|D]) --> letter_or_digit(C), letters_or_digits(D), !.
letters_or_digits([C]) --> letter_or_digit(C), !.
letters_or_digits([]) --> "", !.

letter(C) --> [C], {"a"=<C, C=<"z"}, !.
letter(C) --> [C], {"A"=<C, C=<"Z"}, !.
letter_or_digit(C) --> [C], {"a"=<C, C=<"z"}, !.
letter_or_digit(C) --> [C], {"A"=<C, C=<"Z"}, !.
letter_or_digit(C) --> [C], {"0"=<C, C=<"9"}, !.

table("student").

sbvr2sql --> label(Name), " is an integer.", {assert(fields(Name, "INT"))}.
sbvr2sql --> label(Name), " is a string.", {assert(fields(Name, "VARCHAR(64)"))}.

sbvr2sql(Table, Property)  --> label(Table), " has ", label(Property), ".".

Here is how it works fine:

?- sbvr2sql("age is an integer.", []).
true 

?- sbvr2sql("firstName is a string.", []).
true.

?- sbvr2sql(T, P, "student has firstName.", []).
T = "student",
P = "firstName".

?- fields(F, T).
F = "age",
T = [73, 78, 84] n
F = "firstName",
T = [86, 65, 82, 67, 72, 65, 82, 40, 54|...].

?- sbvr2sql(T, P, "student has firstName.", []), fields(P, _).
T = "student",
P = "firstName".

But it doesn't work here:

?- table(T).
T = [115, 116, 117, 100, 101, 110, 116]. % "student"

?- sbvr2sql(T, P, "student has firstName.", []), table(T).
false.

Apparently it doesn't recognise table("student") as true. It recognises "student" as a label as seen above. What gives?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑脸一如从前 2024-10-21 21:25:38

我无法重现该错误,但我怀疑它可能在您的 label/3 规则中。当我使用此规则的以下定义时:

label([C|S]) -->
    [C], {[Sp|_] = " ", C \= Sp, [Dot|_] = ".", C \= Dot}, !,
    label(S).
label([],X,X).

我得到了正确的结果:

?- sbvr2sql(TS, PS, "student has firstName.", []), table(TS),
   atom_codes(P,PS), atom_codes(T,TS).
TS = [115, 116, 117, 100, 101, 110, 116],
PS = [102, 105, 114, 115, 116, 78, 97, 109, 101],
P = firstName,
T = student.

一般来说,我建议在进行 DCG 操作之前将字符串标记为原子列表。这样,由于 Prolog 的字符串输出很尴尬,调试起来就容易得多。

I can't reproduce the error, but I suspect it may be in your label/3 rule. When I used the following definition of this rule:

label([C|S]) -->
    [C], {[Sp|_] = " ", C \= Sp, [Dot|_] = ".", C \= Dot}, !,
    label(S).
label([],X,X).

I get correct results:

?- sbvr2sql(TS, PS, "student has firstName.", []), table(TS),
   atom_codes(P,PS), atom_codes(T,TS).
TS = [115, 116, 117, 100, 101, 110, 116],
PS = [102, 105, 114, 115, 116, 78, 97, 109, 101],
P = firstName,
T = student.

In general, I'd recommend tokenizing strings into lists of atoms before doing DCG manipulation. That way, it's much easier to debug because of Prolog's awkward string output.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文