/* Amb in Picat. From Rosetta code http://rosettacode.org/wiki/Amb """ Define and give an example of the Amb operator. The Amb operator takes some number of expressions (or values if that's simpler in the language) and nondeterministically yields the one or fails if given no parameter, amb returns the value that doesn't lead to failure. The example is using amb to choose four words from the following strings: set 1: "the" "that" "a" set 2: "frog" "elephant" "thing" set 3: "walked" "treaded" "grows" set 4: "slowly" "quickly" It is a failure if the last character of word 1 is not equal to the first character of word 2, and similarly with word 2 and word 3, as well as word 3 and word 4. (the only successful sentence is "that thing grows slowly"). """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. import cp. main => go. go => amb_example([Word1, Word2, Word3, Word4]), println([Word1, Word2, Word3, Word4]). go2 => amb_example2([Word1, Word2, Word3, Word4]), println([Word1, Word2, Word3, Word4].join(" ")). % a direct approach go3 => member(Word1, ["the","that","a"]), member(Word2, ["frog","elephant","thing"]), member(Word3, ["walked","treaded","grows"]), member(Word4, ["slowly","quickly"]), Words = [Word1,Word2,Word3,Word4], foreach(I in 2..Words.length) Words[I-1].last() = Words[I].first() end, println([Word1,Word2,Word3,Word4]), nl. % Prolog-inspired solution, % from http://rosettacode.org/wiki/Amb#Prolog amb(E, E2) ?=> E2 = [E|_] . amb(E, E2) => E2 = [_|ES], amb(E, ES). joins(Left, Right) => append(_, [T], Left), append([R], _, Right), ( T != R -> amb(_, []) % (explicitly using amb on fail as required) ; true ). amb_example([Word1, Word2, Word3, Word4]) => amb(Word1, ["the","that","a"]), amb(Word2, ["frog","elephant","thing"]), amb(Word3, ["walked","treaded","grows"]), amb(Word4, ["slowly","quickly"]), joins(Word1, Word2), joins(Word2, Word3), joins(Word3, Word4). % Another approach, perhaps not exactly according the task... amb2([],[]) => true. amb2(Word,Words) => member(Word,Words). % joins2(Word1,Word2) => Word1[Word1.length] = Word2[1]. joins2(Word1,Word2) => Word1.last() = Word2.first(). amb_example2([Word1, Word2, Word3, Word4]) => amb2(Word1, ["the","that","a"]), amb2(Word2, ["frog","elephant","thing"]), amb2(Word3, ["walked","treaded","grows"]), amb2(Word4, ["slowly","quickly"]), joins2(Word1,Word2), joins2(Word2,Word3), joins2(Word3,Word4).