【问题标题】:Prolog predicate that do a wrong use of or ;?Prolog 谓词错误使用 or ;?
【发布时间】: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


【解决方案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).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    相关资源
    最近更新 更多