Prolog断言错误地使用或者;?

时间:2013-06-01 10:09:19

标签: prolog logic declarative

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

我有一个令牌列表,其中令牌代表一个单词,我想要识别此列表中的5个连续令牌,表示具有以下形式的日期: 12 Febbraio 1995 其中12是日期编号,Febbraio是月份(使用意大利语),1995年是年份(介于值和另一个之间是空格)

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

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

正如你所看到的一般标记有一个“仿函数”并且有两个参数:一个数字(不一定是渐进的,在某些情况下我有这个值可以是-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)和第二个表示唯一专用令牌的参数(参考前面的示例,这个新令牌将是:** d(1,“12 Febbraio 1995”)具有

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

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

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

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

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

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

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

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

要做到这一点我检查变量值是否为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),

为什么呢?问题是什么?我怎么解决?我想我也可以使用月份列表并说明字符串中是否存在字符串值,但现在我认为我的解释存在一些问题;含义。

1 个答案:

答案 0 :(得分: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).