【发布时间】:2013-06-01 10:09:18
【问题描述】:
我在对特定列表执行特定操作时遇到了一些问题。
我有一个标记列表,其中 标记 代表一个单词,我想识别此列表中的 5 个连续标记是否代表具有以下形式的日期:12 Febbraio 1995 其中 12 是日期,Febbraio 是月份(意大利语),1995 是年份(一个值和另一个值之间是空格)
例如上一个日期是以下标记列表:
[t(1, "12"),t(-1, " "), t(2, "Febbraio"), t(-1, " "), t(3, "1995" )]
正如你所看到的,一个通用标记有一个“函子”t,其中有两个参数:一个数字(不一定是渐进的,在某些情况下我认为这个值可以是 -1)和一个代表 a词。
我已经尝试实现以下谓词,但我发现了一个问题:
tagga([t(Number1, Day), t(-1, Space1), t(Number3, Month), t(-1, Space2), t(Number4, Year)|ListaToken], [d(Number1, CompositeDateTag)|ListaTokenTaggati) :-
length(Day, LnDay),
LnDay =:= 2,
Day = [Head|Tail],
char_type(Head, digit),
Space1 == " ",
Month == "gennaio"; Month == "febbraio"; Month == "marzo"; Month == "aprile"; Month == "maggio"; Month == "giugno"; Month == "luglio";
Month == "agosto"; Month == "settembre"; Month == "ottobre"; Month == "novembre"; Month == "dicembre";
Month == "Gennaio"; Month == "Febbraio"; Month == "Marzo"; Month == "Aprile"; Month == "Maggio"; Month == "Giugno"; Month == "Luglio";
Month == "Agosto"; Month == "Settembre"; Month == "Ottobre"; Month == "Novembre"; Month == "Dicembre",
Space2 == " ",
length(Year, LnYear),
LnYear =:= 4,
NumericString = [Head|Tail],
char_type(Head, digit),
append(Day, Space1, UntilSpace1),
append(UntilSpace1, Month, UntilMonth),
append(UntilMonth, Space2, UntilSpace2),
append(UntilSpace2, Year, CompositeDateTag),
write(CompositeDateTag),
tagga(ListaToken, ListaTokenTaggati).
如您所见,我的 tagga/2 谓词作为第一个参数 五个可以表示日期的标签(如果规则的主体为 TRUE)和第二个表示唯一专用令牌的参数(参考前面的示例,这个新令牌将是:**d(1, "12 Febbraio 1995"),具有
因此,要创建新的专用令牌,它必须检查某些属性是否为真:
1) 第一个通用token的内容代表一天:必须是2位数字组成的数字
2) 第二个通用记号的内容是一个空格“”
3) 第三个通用标记的内容是意大利语月份的名称
4) 第四个通用令牌的内容代表一天:所以它必须是由2位数字组成的数字
5)第五个通用token的内容代表一年所以必须是4位数字组成的数字
最后创建了新的专用数据标记的内容,即 CompositeDateTag 变量
检查第三个通用令牌的内容是否属于月份名称列表后出现问题。
为此,我检查 Month 变量值是否为 gennaio OR febbraio OR marzo 等等,使用 ; 运算符为 OR 但现在出了点问题,实际上我得到了以下跟踪:
[trace] ?- tagga([t(1, "12"),t(-1, " "), t(2, "febbraio"), t(-1, " "), t(3, "1995")], NewToken).
Call: (6) tagga([t(1, [49, 50]), t(-1, [32]), t(2, [102, 101, 98, 98|...]), t(-1, [32]), t(3, [49, 57|...])], _G445) ? creep
Call: (7) length([49, 50], _G602) ? creep
Exit: (7) length([49, 50], 2) ? creep
^ Call: (7) 2=:=2 ? creep
^ Exit: (7) 2=:=2 ? creep
Call: (7) [49, 50]=[_G594|_G595] ? creep
Exit: (7) [49, 50]=[49, 50] ? creep
Call: (7) char_type(49, digit) ? creep
Exit: (7) char_type(49, digit) ? creep
Call: (7) [32]==[32] ? creep
Exit: (7) [32]==[32] ? creep
Call: (7) [102, 101, 98, 98, 114, 97, 105, 111]==[103, 101, 110, 110, 97, 105, 111] ? creep
Fail: (7) [102, 101, 98, 98, 114, 97, 105, 111]==[103, 101, 110, 110, 97, 105, 111] ? creep
Call: (7) [102, 101, 98, 98, 114, 97, 105, 111]==[102, 101, 98, 98, 114, 97, 105, 111] ? creep
Exit: (7) [102, 101, 98, 98, 114, 97, 105, 111]==[102, 101, 98, 98, 114, 97, 105, 111] ? creep
Exit: (6) tagga([t(1, [49, 50]), t(-1, [32]), t(2, [102, 101, 98, 98|...]), t(-1, [32]), t(3, [49, 57|...])], [d(1, _G592)|_G589]) ? creep
NewToken = [d(1, _G592)|_G589]
如您所见,似乎在传递的月份字符串“febbraio”和月份列表中的值之间找到了正确的匹配项,事实上:
Call: (7) [102, 101, 98, 98, 114, 97, 105, 111]==[102, 101, 98, 98, 114, 97, 105, 111] ? creep
Exit: (7) [102, 101, 98, 98, 114, 97, 105, 111]==[102, 101, 98, 98, 114, 97, 105, 111] ? creep
但似乎跳过再次调用 tagga/2 谓词而不执行我的代码中的以下检查,这些:
Space2 == " ",
length(Year, LnYear),
LnYear =:= 4,
NumericString = [Head|Tail],
char_type(Head, digit),
为什么?问题是什么?我该如何解决?我认为我也可以使用月份列表并说明字符串中是否存在字符串值,但现在我认为我对 ; 的解释存在一些问题意思。
【问题讨论】:
-
什么是
{{...}}? -
我不知道是什么 {{ ... ; ... }} 表示(除了库(clpqr))。这是你的控制结构?
-
nono 我刚刚从我的代码中删除...这是旧版本的代码...现在我没有{{}}
-
但你应该有括号
( ... ; ... )。无论如何,memberchk(Month, ["gennaio","febbraio"...])它要好得多,即使在性能方面也是如此。 -
@AndreaNobili 这不仅是为了帮助您,也是为了帮助未来的读者。 :) 您应该 (A) 解释问题所在和解决方案,或者 (B) 删除此问题。
标签: prolog logic declarative