prologcrossword

Learning Prolog: solving a crossword scheme


I'm trying to learn Prolog following the tutorials on this site and I can't find a solution to an exercise (and there's no solution on the site).

Here's what I have to do:

Here are six Italian words:

astante , astoria , baratto , cobalto , pistola , statale .

They are to be arranged, crossword puzzle fashion, in the following grid:

scheme

The following knowledge base represents a lexicon containing these words:

  • word(astante, a,s,t,a,n,t,e).
  • word(astoria, a,s,t,o,r,i,a).
  • word(baratto, b,a,r,a,t,t,o).
  • word(cobalto, c,o,b,a,l,t,o).
  • word(pistola, p,i,s,t,o,l,a).
  • word(statale, s,t,a,t,a,l,e).

Write a predicate crossword/6 that tells us how to fill in the grid. The first three arguments should be the vertical words from left to right, and the last three arguments the horizontal words from top to bottom.

Now, the same question has been asked there but each given solution uses things that I don't know (and I'm not supposed to know to solve this).

To clarify, while the things in the linked question are surely working, they use stuff that hasn't been explained yet in the guide that I'm following, and this means that I need to solve the exercise without using that kind stuff, so no maplist and things like that.

My idea was to fill the board with the letters from the given words, with some constraints:

and so on..

So here's my code:

word(astante,  a,s,t,a,n,t,e).
word(astoria,  a,s,t,o,r,i,a).
word(baratto,  b,a,r,a,t,t,o).
word(cobalto,  c,o,b,a,l,t,o).
word(pistola,  p,i,s,t,o,l,a).
word(statale,  s,t,a,t,a,l,e). 

crossword(V1,V2,V3,H1,H2,H3):- word(V1, V11,V12,V13,V14,V15,V16,V17),
                               word(H1, H11,V12,H13,H14,H15,H16,H17),
                               word(H2, H21,V14,H23,H24,H25,H26,H27),
                               word(H3, H31,V16,H33,H34,H35,H36,H37),

                               word(V2, V21,V22,V23,V24,V25,V26,V27),
                               word(H1, H11,H12,H13,V22,H15,H16,H17),
                               word(H2, H21,H22,H23,V24,H25,H26,H27),
                               word(H3, H31,H32,H33,V26,H35,H36,H37),

                               word(V3, V31,V32,V33,V34,V35,V36,V37),
                               word(H1, H11,H12,H13,H14,H15,V32,H17),
                               word(H2, H21,H22,H23,H24,H25,V34,H27),
                               word(H3, H31,H23,H33,H34,H35,V36,H37). 

(I'm sorry if this is not formatted well but I still don't know what's the correct indentation style for Prolog).

Of course, event if my idea seems correct (at least to me), this code returns No and I don't know why.

Any hint on this?

EDIT:

Following @mbratch's comment, I've tried using the code found in this solution.

Here's the code:

crossword(V1, V2, V3, H1, H2, H3) :-
   word(V1, V1a, V1bH1b, V1c, V1dH2b, V1e, V1fH3b, V1g), 
   word(V2, V2a, V2bH1d, V2c, V2dH2d, V2e, V2fH3d, V2g), 
   word(V3, V3a, V3bH1f, V3c, V3dH2f, V3e, V3fH3f, V3g), 
   word(H1, H1a, V1bH1b, H1c, V2bH1d, H1e, V3bH1f, H1g), 
   word(H2, H2a, V1dH2b, H2c, V2dH2d, H2e, V3dH2f, H2g), 
   word(H3, H3a, V1fH3b, H3c, V2fH3d, H3e, V3fH3f, H3g).

The code works, but it has a problem with duplicates which I don't mind.

What I'd like to understand is why this one works while mine returns No.


Solution

  • After few tries, and based on @joel76's comment, I noticed that my first code was wrong because I declared H1,H2 and H3 multiple times, so the result computed in the second line was being changed in the sixth and this led to the No returned by Prolog.

    So, instead of doing things in multiple lines, I merged them with this result:

    crossword(V1,V2,V3,H1,H2,H3):- word(V1, V11, V12, V13, V14, V15, V16, V17),
                                   word(V2, V21, V22, V23, V24, V25, V26, V27),
                                   word(V3, V31, V32, V33, V34, V35, V36, V37),
                                   word(H1, H11, V12, H13, V22, H15, V32, H17),
                                   word(H2, H21, V14, H23, V24, H25, V34, H27),
                                   word(H3, H31, V16, H33, V26, H35, V36, H37).
    

    and now it's working.