2

Searching on StackOverflow I have found this DCG grammar that say inf a string is a roman number and convert it into a decimal number (in this post: Prolog Roman Numerals (Attribute Grammars)):

roman(N) -->
    group('C','D','M',100, H),
    group('X','L','C',10, T),
    group('I','V','X',1, U),
    {N is H+T+U}.
group(A,B,C, Scale, Value) -->
    (   g3(A, T)
    ;   [A, B], {T = 4}
    ;   [B], g3(A, F), {T is 5+F} % thanks to Daniel for spotting the bug
    ;   [A, C], {T = 9}
    ;   {T = 0}
    ),  {Value is Scale * T}.

g3(C, 1) --> [C].
g3(C, 2) --> [C,C].
g3(C, 3) --> [C,C,C].

This work well but I can't understand how it work.

So I have 3 predicatse:

1) group/5 that take 4 parameters: C, D, M, 100 (where I think that C, D and M represents the multiplicative factor 100.

So what exactly represent H? Is it the sum of the letters that represent the component of finaldecimal number having 100 as multiplicative factor?

In the same way it is definied the version of group/3 predicate for multiplicative factor 10 (X,L,C) and a version of group/3 predicate for multiplicative factor 1 (I,V,X)

So I read the roman/1 predicate in this way: ** An integer number N is a roman number composed by a group of letters that represents the multiplicative factor 100, followed by a group of letters that represents the multiplicative factor 10, followed by the group of letters that represents the multiplicative factor 1.

And have to be TRUE that H+T+U is my original decimal number (where H+T+U is the sum of the letters that represent the component of finaldecimal number having 10 as multiplicative factor + he sum of the letters that represent the component of finaldecimal number having 100 as multiplicative factor + he sum of the letters that represent the component of finaldecimal number having 1 as multiplicative factor)

Is it my reasoning correct or am I missing something?

Now, if my previous reasoning is correct, I have some problem to understand how the group/3 predicate work and what exactly do the g3/2 predicate

Can you help me?

Tnx

Andrea

Community
  • 1
  • 1
AndreaNobili
  • 40,955
  • 107
  • 324
  • 596
  • 2
    Note that the code you posted doesn't define predicates but non-terminals: roman//1, group//5, and g3//2 (of course, these non-terminals are translated into predicates when compiled and loaded). – Paulo Moura Jun 05 '13 at 20:23

1 Answers1

1

Your understanding seems right to me.

group//5 is parametrized with

  • A the group letter (1 to 3, expressed by g3, like III = 3)
  • B the midpoint letter (like VI = 6)
  • C the group letter of successive scale, to be used when subtracting (like IX = 9).

then a group of given scale can have any of these five patterns, giving the numerical value, to be scaled. As I noted in the original post, I like the compactness of this grammar.

CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • Now is a litle clear for me but I still have some douts :-( So, if I have understand, the g3/3 predicate creates only the roman numbers I, II, III (1,2,3 in decimal). So relatively to the group/5 predicate I think that A,B,C variable could unify with C,D,M roman number value and the Scale variable unify with 100 multiplicative factor for the first group of letter that made up the roman number, so on: A,B,C unify with X,L,C roman number and Scale unify with 10 for the second group that made up the roman number and finnally A,B,C unify with: I, V, X and Scale uniffy with 1 for the third group – AndreaNobili Jun 06 '13 at 15:24
  • If this is true (I hope...) the group/5 predicate build each group with the body of the grammar rule using a set of exclusive or: so a group could be something: g3(A, T) that could value only I or II or II. Or a group could be [A, B], {T = 4} that means that A=I and B=5 (why? this is not clear for me), or could be [B], g3(A, F), {T is 5+F} and so one...I am finding some difficulties to understand this part of code...if there is not a problem for you can you post me a pair of example about how a number will build starting to the first non terminal? tnx so much – AndreaNobili Jun 06 '13 at 15:29