Coding Challenge #27 (2 weeks): The Twelve Days of Christmas

Definite Clause Grammars (DCGs) are ideally suited for reasoning about text, including parsing and also describing it.

For example, in this case, we can generate the lyrics from a declarative description:

:- use_module(library(dcgs)).
:- use_module(library(format)).

day_gift("first", "A partridge in a pear tree.").
day_gift("second", "Two turtle doves").
day_gift("third", "Three french hens").
day_gift("fourth", "Four calling birds").
day_gift("fifth", "Five golden rings").
day_gift("sixth", "Six geese a-laying").
day_gift("seventh", "Seven swans a-swimming").
day_gift("eight", "Eight maids a-milking").
day_gift("ninth", "Nine ladies dancing").
day_gift("tenth", "Ten lords a-leaping").
day_gift("eleventh", "Eleven pipers piping").
day_gift("twelth", "Twelve drummers drumming").


lyrics -->
        { findall(D-G, day_gift(D, G), DGs) },
        stanzas(DGs, []).

stanzas([], _) --> [].
stanzas([Day-Gift|DGs], Prev) -->
        format_("On the ~s day of Christmas~n", [Day]),
        "My true love gave to me:\n",
        format_("~s", [Gift]),
        previous_gifts(Prev),
        stanzas(DGs, [Gift|Prev]).

previous_gifts([]) --> "\n\n".
previous_gifts([G|Gs]) --> previous_(Gs, G).

previous_([], G) -->
        format_(" and~n~s~n~n", [G]).
previous_([G|Gs], Current) -->
        format_("~n~s", [Current]),
        previous_(Gs, G).

Sample query:

?- phrase(lyrics, Ls), format("~s", [Ls]).
On the first day of Christmas
My true love gave to me:
...

Including the binding Ls = "On the first day of ...", which can be used for reasoning about the text.

Thank you for this interesting puzzle, and Merry Christmas!

/r/prolog Thread