go => test_it(check_word), test_it(check_word2), nl. % Get all possible solutions (via fail) go2 ?=> test_version(check_word2), fail, nl. go2 => true. % % Test a version. % test_it(Pred) => println(testing=Pred), Blocks = findall([A,B], block(A,B)), Words = findall(W,word(W)), foreach(Word in Words) println(word=Word), ( call(Pred,Word,Blocks) ; println("Cannot make word.")), nl end, nl. % % Picat style: Using nth/3 for getting the chars % check_word(Word, Blocks) => WordC = atom_chars(Word), % convert atom to string WordLen = length(WordC), X = new_list(WordLen), Pos = new_list(WordLen), foreach(I in 1..WordLen) % find a character at the specific position nth(X[I],Blocks,XI), nth(Pos[I],XI, WordC[I]) end, alldiff(X), % ensure unique selection foreach(I in 1..WordLen) println([WordC[I], Blocks[X[I]]]) end, nl. % % Prolog style (recursive) version using select/3. % (where we don't have to worry about duplicate blocks) % check_word2(Word, Blocks) :- pick_block(atom_chars(Word),Blocks,[],X), println(X). pick_block([], _,Res,Res). pick_block([C|WordRest], Blocks, Res1,[Block|Res]) :- % pick (non-deterministically) one of the blocks select(Block,Blocks,BlocksRest), membchk(C,Block), pick_block(WordRest,BlocksRest,Res1,Res). % % alldiff(L): % ensure that all elements in L are different % alldiff([]). alldiff([_]). alldiff([H|T]) :- neq(H,T), alldiff(T). neq(_,[]). neq(X,[H|T]) :- X != H, neq(X,T). % The words to check. word(a). word(bark). word(book). word(treat). word(common). word(squad). word(confuse). word(auto). word(abba). word(coestablishment). word(schoolmastering). % The blocks block(b,o). block(x,k). block(d,q). block(c,p). block(n,a). block(g,t). block(r,e). block(t,g). block(q,d). block(f,s). block(j,w). block(h,u). block(v,i). block(a,n). block(o,b). block(e,r). block(f,s). block(l,y). block(p,c). block(z,m).