我正在完成一项任务,我被困在了。我对prolog的经验很少,而且我正在学习基于在线资料和教科书的工作。
赋值的目的是生成一个谓词parse(),它能够检查给定的参数/术语是否具有以下形式,并在适当时返回true或false:
这是一个int对,后跟一个n大小的(int,float)对列表,两者都包含在一个元组中。
例如:
有人能指出我正确的方向,从哪里开始吗?我在Prolog中从未这样做过。
我不是在寻找一个完整的编码答案,当然这是一个任务,但只是如何处理这个问题的一些方向。我没有声明性的编程背景,所以这是一个教育练习。
谢谢!
答案 0 :(得分:1)
我们可以从观察开始,你所展示的是已经是一个有效的Prolog术语:
?- T = ( (1, 7), [(1, 0.0), (2, 0.5), (3, 0.7), (4, 0.8), (5, 0.8), (6, 0.25), (7, 0.3)] ) . T = ((1, 7), [(1, 0.0), (2, 0.5), (3, 0.7), (4, 0.8), (5, 0.8), (6, 0.25), (7, 0.3)]).
因此,在这种情况下,不需要手动解析。通过解析,我们通常意味着将非结构化文本(例如字符或字符代码的简单列表)转换为结构化< / strong>代表。
Prolog 自动拒绝非语法有效的字词。所以,在你的情况下, if 你已经有了这样一个术语,只需说明持有的内容,以便它满足所有约束条件。
在Prolog中,首先考虑您可能希望用作有用基础的构建块通常很有用。例如,让我们描述一个(int,float)
术语:
integer_float_tuple((I,F)) :- integer(I), float(F).
我们可以按如下方式使用它:
?- integer_float_tuple((3,4.5)). true.
请注意:
?- integer_float_tuple(T).
也会失败!(A,B)
形式的术语,因为(',')/2
已用于Prolog中的许多其他内容。最好将这些对表示为I-F
,使用(-)/2
,这通常用于表示Prolog库中的对。无论如何,我们可以使用以下内容构建此定义:
good_term((Tuple,Tuples)) :- Tuple = (A,B), integer(A), integer(B), maplist(integer_float_tuple, Tuple).
这说明了这些条款必须包含的所有内容,因此可以验证它们,但如上所述,不是生成它们。要概括此类谓词在所有方向上工作,请使用Prolog系统的CLP(FD)和CLP(R)约束。这将为您提供单调的定义,并满足我们期望从逻辑程序中获得的许多理想属性。
此外,如果你真的想手动解析你的数据(而不是依赖Prolog内置的结构化术语概念),我有两个建议:< / p>
首先,将以下指令添加到您的程序中: 这使您可以使用双引号方便地编写字符列表。 例如: 这样的表示非常方便我们接下来要做的事情,即使用Prolog Definite Clause Grammars 来解析这样的字符列表。 我不会为你解决整个任务,但我会给你一个开始。我们可以从描述数字的含义开始: 我们在 在此定义的基础上,让我们描述数字的列表: 示例查询: 最后,让我们将所有这些组合成一个整数: 使用 示例查询: 使用这些构建基块,您可以通过其他语法元素方便地描述此类字符列表的一般大纲。 总的来说,您最终的语法可能如下所示: 您需要提供 有关此方法的详情,请参阅dcg。:- set_prolog_flag(double_quotes, chars).
?- Cs = "abc".
Cs = [a, b, c].
digit(D) --> [D], { char_type(D, digit) }.
phrase/2
接口谓词中使用这样的语法。例如:?- phrase(digit(D), "5").
D = '5'.
digits([]) --> [].
digits([D|Ds]) --> digit(D), digits(Ds).
?- phrase(digits(Ds), "5235").
Ds = ['5', '2', '3', '5'] ;
false.
integer(I) --> digit(D), digits(Ds), { number_chars(I, [D|Ds]) }.
number_chars/2
,我们正在执行字符与实际整数之间的关键转换,您需要在自己的代表中进行转换。?- phrase(integer(I), "5235").
I = 5235 ;
false.
pattern --> "(", whitespace, "(", integer, ",", integer, ")", ...
whitespace//0
的定义并完成整个说明。
答案 1 :(得分:0)
在Prolog中,我们编写谓词,而不是函数,在最基本的情况下,只能限定关系的“真实性” - 通常由谓词的“名称”描述,所谓的仿函数 - 参数之中。
所以,你正在写 3 参数之间的关系:
parse(Needle, Haystack, Found) :-
...
你应该写下另一个关系,当Needle
匹配Haystack
的一个元素时,这种关系就成立了。所以你可以选择:递归解析/ 3,其中要匹配的当前元素在头部模式中显式(即parse(Needle, [Element|Haystack], Found) :- etc
)或使用库中的member / 2(列表) ), on backtracking 将迭代元素......