Question

Hello I am new Prolog and DGC.I want to write a DCG to parse time expressions like 10.20 am or 12 oclock. how can I check 10.20 am is valid expression or not for Olcock I wrote some code.

oclock --> digit1,phrase1.

digit1 --> [T],{digit1(T)}.
digit1(1).
digit1(2).
digit1(3).
digit1(4).
digit1(5).
digit1(6).
digit1(7).
digit1(8).
digit1(9).
digit1(10).
digit1(11).
digit1(12).

phrase1 --> [P],{phrase1(P)}.
phrase1(Oclock).

i ma checking by query

oclock([1,oclock],[]).

can someone help me on this.

Was it helpful?

Solution

A quick note about your existing code:

In your definition phrase1(Oclock), Oclock is left completely undetermined, which means that anything will count as phrase1. Thus, your DCG rule for phrase1\\0 will be true for any single element list:

?- phrase(phrase1, X).
X = [_G481].

?- phrase(phrase1, [a]).
true.

?- phrase(phrase1, [abababab]).
true.

?- phrase(phrase1, [[aba,dbdi,dbdi]]).
true.

?- phrase(phrase1, []).
false.

A possible solution to your question:

Here is one possible solution:

time --> hours, suffix. 

suffix  --> sep, minutes, meridiem.
suffix  --> ['oclock'].

hours   --> {between(1,12,H)}, [H].
sep     --> ['.'].
minutes --> {between(1,60,M)}, [M].

meridiem --> [am].
meridiem --> [pm].

Test it with the query:

?- phrase(time, [1,'.',10,am]).
true.

phrase/2 or phrase/3 are the standard predicates for calling DCG rules. You can also query phrase(time, X) and see X instantiated with all possible times.

Just in case there is any confusion, both this solution and your own will only work for strings of atoms, but not strings of characters. So if you're trying to parse natural language by reading in a file, you'll have to do some work either converting the characters input into atoms or make the dcg deal with characters instead. E.g.,

time --> hours, suffix. 

suffix  --> sep, minutes, meridiem.
suffix  --> " oclock".

hours   --> {hours(H)},  H.
sep     --> ".".
minutes --> {minutes(M)}, M.

meridiem --> " am".
meridiem --> " pm".

hours(H)    :-
    between(1,12,N),
    atom_codes(N,H).
minutes(M)  :-
    between(1,60,N),
    atom_codes(N,M).

Lists of atoms have been exchanged for lists of character codes; since?- A = "aaa". A = [97, 97, 97]. In SWI-Prolog, conversion between atoms and code characters can be achieved through predicates listed here: file:///opt/local/lib/swipl-6.4.1/doc/Manual/manipatom.html#atom_chars/2

There are many more character related predicates to found in the manual.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top