I have solved this exercise, but I dont think my result is as readable
or concise as it could be.
Any feedback on how to improve this program is appreciated.
One thing is for certain. If this were a generic crossword puzzle
solver, you would probably de-construct each word into a list of
letters instead of using a bunch of functors of varying arity (I
suppose).
word(abalone,a,b,a,l,o,n,e).
word(abandon,a,b,a,n,d,o,n).
word(enhance,e,n,h,a,n,c,e).
word(anagram,a,n,a,g,r,a,m).
word(connect,c,o,n,n,e,c,t).
word(elegant,e,l,e,g,a,n,t).
crosswd(WH1,WH2,WH3,WV1,WV2,WV3) :-
word(WH1,_,H12,_,H14,_,H16,_),
word(WH2,_,H22,_,H24,_,H26,_),
word(WH3,_,H32,_,H34,_,H36,_),
word(WV1,_,H12,_,H22,_,H32,_),
word(WV2,_,H14,_,H24,_,H34,_),
word(WV3,_,H16,_,H26,_,H36,_).
word(abalone, "abalone").
word(abandon, "abandon").
word(enhance, "enhance").
word(anagram, "anagram").
word(connect, "connect").
word(elegant, "elegant").
crosswd(WH1,WH2,WH3,WV1,WV2,WV3) :-
word(WH1, [_,H12,_,H14,_,H16,_]),
word(WH2, [_,H22,_,H24,_,H26,_]),
word(WH3, [_,H32,_,H34,_,H36,_]),
word(WV1, [_,H12,_,H22,_,H32,_]),
word(WV2, [_,H14,_,H24,_,H34,_]),
word(WV3, [_,H16,_,H26,_,H36,_]).
In my opinions, your program is readable. And a more articulate
program may be as follows, that you can construct a crossword set if
you describe what place two words meet in. The program works in SWI-
Prolog.
word(abalone).
word(abandon).
word(enhance).
word(anagram).
word(connect).
word(elegant).
element_at([X|_], 1, X).
element_at([_|Y], N, Z) :- element_at(Y, N1, Z), N is N1 + 1.
meet_at(W1, Pos1, W2, Pos2) :- W1 \= W2,
atom_to_chars(W1, S1), atom_to_chars(W2, S2),
element_at(S1, Pos1, X), element_at(S2, Pos2, X).
crosswd(V1, V2, V3, H1, H2, H3) :-
word(V1), word(V2), word(V3),
word(H1), word(H2), word(H3),
meet_at(V1, 2, H1, 2),
meet_at(V2, 2, H1, 4),
meet_at(V3, 2, H1, 6),
meet_at(V1, 4, H2, 2),
meet_at(V2, 4, H2, 4),
meet_at(V3, 4, H2, 6),
meet_at(V1, 6, H3, 2),
meet_at(V2, 6, H3, 4),
meet_at(V3, 6, H3, 6).
What about this? This is fully ISO compliant as well.
meet_at(W1, Pos1, W2, Pos2) :-
W1 \== W2, % or use dif/2, but not \=
sub_atom(W1, Pos1, 1, _, X),
sub_atom(W2, Pos2, 1, _, X).
Cheers --- Jan