-1

I am having some problem to do a specific operation on a specific list.

I have a list of tokens where a token represents a word and I want recognize if 5 contiguous tokens in this list, represents a date having the form: 12 Febbraio 1995 where 12 is the day number, Febbraio is the month (in the Italian language) and 1995 is the year (and between a value and the other is a blank space)

For example the previous date is the following tokens list:

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

As you can see a general token have a "functor" t and into it there are two arguments: a number (not necessarily progressive, in some cases I have that this value can be -1) and a string that represent a word.

I have try to implement the following predicate but I am finding a problem:

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).

as you can see my tagga/2 predicate have as first paramether five tags that could represent a date (if the body of the rule is TRUE) and a second parameter that represents a unique specialized token (referring to the previous example this new token will be: **d(1, "12 Febbraio 1995") that have the

So, to create the new specialized token it have to check that some properties are true as:

1) The content of the first general token represents a day: so it have to be a number composed of 2 digits

2) The content of the second general token is a white space " "

3) The content of the third general token is the name of a months in Italian language

4) The content of the fourth general token represents a day: so it have to be a number composed of 2 digits

5) The content of the fifth general token represents an year so it have to be a number composed of 4 digits

Finally it is created the content of the new specialized data token that is the CompositeDateTag variable

The problem occurs after that it check if the content of the third general token belongs to the list of the months name.

to do this I check if the Month variable value is gennaio OR febbraio OR marzo and so on, using the ; operator as OR but now something go wrong, in fact I obtain the following trace:

[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] 

As you can see seems that find the right match between the passed month string "febbraio" and a value into a month list, infact:

   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

but then seem that skip over calling again the tagga/2 predicate without execute the following checks that are in my code, these:

    Space2 == " ",

length(Year, LnYear),
LnYear =:= 4,
NumericString = [Head|Tail],
char_type(Head, digit),

Why? What is the problem? How can I solve? I think that I can also use a month list and say if the string value is present in the string but now I think that there is some problem with my interpretation of ; meaning.

false
  • 10,264
  • 13
  • 101
  • 209
AndreaNobili
  • 40,955
  • 107
  • 324
  • 596
  • what is `{{` ... `}}`? – Will Ness Jun 01 '13 at 10:37
  • I can't tell what {{ ... ; ... }} means (apart library(clpqr)). It's your control structure ? – CapelliC Jun 01 '13 at 10:37
  • nono I have just removed from my code...this was an old version of code...now I have not {{}} – AndreaNobili Jun 01 '13 at 10:40
  • 1
    but you should have parenthesis `( ... ; ... )`. Anyway, `memberchk(Month, ["gennaio","febbraio"...])` it's far better, even for performance. – CapelliC Jun 01 '13 at 10:41
  • please copy and paste the source code **as is** from the working source file. then copy and paste **as is** your call, and the response you get from the Prolog prompt. I think you didn't copy the code, and there's a typo there (there's also a syntax error; the code *as is* couldn't have worked). – Will Ness Jun 01 '13 at 16:14
  • Solved with CapelliC tricks tnx guys ;-) – AndreaNobili Jun 01 '13 at 17:55
  • 1
    @AndreaNobili this is not only to help *you*, but future readers as well. :) You should either (A) explain what was the problem and the solution, or (B) remove this question. – Will Ness Jun 02 '13 at 21:05
  • @Will Ness You are right, so I have posted my final solution of this problem :-) – AndreaNobili Jun 03 '13 at 09:30

1 Answers1

1

This is my final solution to the problem, using the CapelliC idea based on a list:

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).
Will Ness
  • 70,110
  • 9
  • 98
  • 181
AndreaNobili
  • 40,955
  • 107
  • 324
  • 596