-1

我在特定列表上执行特定操作时遇到了一些问题。

我有一个标记列表,其中标记代表一个单词,我想识别此列表中的 5 个连续标记是否代表具有以下形式的日期:12 Febbraio 1995其中 12 是日期,Febbraio 是月份(意大利语) 和 1995 是年份(并且一个值和另一个值之间是一个空格)

例如,前一个日期是以下标记列表:

[t(1, "12"),t(-1, " "), t(2, "Febbraio"), t(-1, " "), t(3, "1995")]

正如您所看到的,一个通用标记有一个“函子”t,其中有两个参数:一个数字(不一定是渐进的,在某些情况下我认为这个值可以是 -1)和一个表示单词的字符串。

我尝试实现以下谓词,但我发现了一个问题:

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),第二个参数表示唯一的专用标记(参考前面的示例,这个新标记将be: **d(1, "12 Febbraio 1995") 具有

因此,要创建新的专用令牌,它必须检查某些属性是否为真,如下所示:

1)第一个通用令牌的内容代表一天:所以它必须是由2位数字组成的数字

2)第二个通用token的内容是一个空格“”

3)第三个通用标记的内容是意大利语月份的名称

4)第四个通用令牌的内容代表一天:所以它必须是由2位数字组成的数字

5)第五个通用令牌的内容代表一年,所以它必须是一个由4位数字组成的数字

最后创建新的专用数据标记的内容,即CompositeDateTag变量

问题出现在它检查第三个通用令牌的内容是否属于月份名称列表之后

为此,我使用;检查Month变量值是否为 gennaiofebbraiomarzo 等等。运算符为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),

为什么?问题是什么?我该如何解决?我认为我也可以使用月份列表来说明字符串中是否存在字符串值,但现在我认为我对 ; 的解释存在一些问题。意义。

4

1 回答 1

1

这是我对这个问题的最终解决方案,使用基于列表的 CapelliC 想法:

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 =:= 1; LnDay =:= 2),
    Day = [Head|Tail],   char_type(Head, digit),

    Space1 == " ",

    member(Month, 
           ["gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno",
            "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre",
            "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", 
            "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "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),

    tagga(ListaToken, ListaTokenTaggati).
于 2013-06-03T09:29:51.977 回答