tag:blogger.com,1999:blog-4650294074444534066.post4293541267729041891..comments2014-04-21T18:15:48.457-07:00Comments on Typed Logic: Attributed Variables: their uses and one implementationgeophfhttp://www.blogger.com/profile/09936874508556500234noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-4650294074444534066.post-84148636189694074122011-11-29T23:42:05.688-08:002011-11-29T23:42:05.688-08:00Thanks for sharing your info. I really appreciate ...Thanks for sharing your info. I really appreciate your efforts and I will be waiting for your further write ups thanks once again.<br /><a href="http://vetech-matlab.blogspot.com" rel="nofollow"> Vee Eee Technologies</a>|Movies Gallery 2011http://www.blogger.com/profile/13879206228609491492noreply@blogger.comtag:blogger.com,1999:blog-4650294074444534066.post-52677328098180988582011-06-12T20:17:19.504-07:002011-06-12T20:17:19.504-07:00@Sjoerd Visscher
Nice! Others have even gone so f...@Sjoerd Visscher<br /><br />Nice! Others have even gone so far as to reduce solve' simply to the function filter, proving to me, again, that I keep reinventing the prelude.geophfhttp://www.blogger.com/profile/09936874508556500234noreply@blogger.comtag:blogger.com,1999:blog-4650294074444534066.post-51286706750088847822011-06-12T20:14:58.427-07:002011-06-12T20:14:58.427-07:00@Daniel Wagner:
Really neat, concise implementati...@Daniel Wagner:<br /><br />Really neat, concise implementation! I've submitted this entry to The Monad.Reader along with your list implementation, credited to you. We'll see how my editor takes it, but thank you for your approach.<br /><br />Lists are great for enumerated domains, but I also like attributed variables in that they make explicit what the domain is and what its constraints are, and that helps me when I'm considering a problem amendable to constraining.<br /><br />Furthermore, I present the base level of attributed variables. Attributed variables in one domain may be related to each other (e.g. av1 + av2 < av3 where avN are attributed variables) giving further expressive power to the programmer. I hope to explore this avenue when I work out how to relate attributed variables in the same domain.<br /><br />Thanks again for your response to my post!geophfhttp://www.blogger.com/profile/09936874508556500234noreply@blogger.comtag:blogger.com,1999:blog-4650294074444534066.post-62018185101212774532011-04-21T11:39:28.800-07:002011-04-21T11:39:28.800-07:00I most definitely didn't understand the point ...I most definitely didn't understand the point of these attributed variables. Consider this much lighterweight implementation:<br /><br />type Attribute a = [a]<br />type Constraint a = a -> Bool<br />type Domain a = [a]<br /><br />makeAttribute = id<br />constrain [x] f = [x] -- see footnote 8, though I think this is a weird choice<br />constrain xs f = filter f xs<br /><br />Note that the helper functions "solve", "solve'", and "solveConstraints" are totally unnecessary in this setting. There's no need to recheck that all the values left in your domain still satisfy all the constraints they used to satisfy, thanks to referential transparency.<br /><br />If you make the other choice re: ground variables (i.e. that they can be revoked when a constraint rules them out), the implementation of "constrain" is even lighter: constrain = flip filter. The implementation is so lightweight, in fact, that I don't even think I'd write it down -- I'd just eliminate calls to makeAttribute and write filter instead of constrain!<br /><br />Here are a few much more minor observations:<br /><br />* Although you don't show the definition, I assume "domain (Attribute _ xs) = xs; domain (Ground x) = [x]". In the lightweight implementation above, we have "domain = id", so I omit it.<br /><br />* Since I haven't introduced any new types (e.g. via "data" or "newtype"), I can't define a new Ord instance -- but that's okay, we can just use "sortBy".<br /><br />* I prefer pattern-matching to guards in "trib".<br /><br />* The code can be considerably simpler if you know that the first argument to kakuro will always be a list of zeros -- which seems reasonable, since any nonzero can just be subtracted from the total -- you can encode the list by just passing its length, inline trib, etc. I didn't do this.<br /><br />Despite the new implementation of attributed variables, the definition of kakuro looks much the same (module the suggestions I made above) and behaves identically on the examples you gave:<br /><br />prioritize :: [Attribute Int] -> [Attribute Int]<br />prioritize = sortBy (comparing length)<br /><br />kakuro :: [Int] -> Int -> [[Int]]<br />kakuro list total = nub $ summer (prioritize $ map trib list) [] total<br /><br />trib :: Int -> Attribute Int<br />trib 0 = [1..9]<br />trib x = [x]<br /><br />summer :: [Attribute Int] -> [Int] -> Int -> [[Int]]<br />summer [] list total = do<br /> guard $ sum list == total<br /> return $ sort list<br />summer (h:t) list total = do<br /> a <- constrain h (flip notElem list)<br /> summer t (a:list) total<br /><br />Overall, it was a neat article, but I think you did some things in a way that was too complicated for your problem. =)Daniel Wagnerhttp://www.blogger.com/profile/07780416306029284400noreply@blogger.comtag:blogger.com,1999:blog-4650294074444534066.post-68406466874399224472011-04-20T10:56:45.258-07:002011-04-20T10:56:45.258-07:00Although i now realize that in your formulation, y...Although i now realize that in your formulation, you can't narrow an infinite domain to a single ground variable anyway, so...gbhttp://www.blogger.com/profile/01816008234963145610noreply@blogger.comtag:blogger.com,1999:blog-4650294074444534066.post-2532488203838858782011-04-20T09:35:53.163-07:002011-04-20T09:35:53.163-07:00Solve should use pattern matching rather than call...Solve should use pattern matching rather than calling length -- that way you can have infinite domains.gbhttp://www.blogger.com/profile/01816008234963145610noreply@blogger.comtag:blogger.com,1999:blog-4650294074444534066.post-79814608541609155912011-04-20T02:48:09.932-07:002011-04-20T02:48:09.932-07:00For consistency reasons you should
actually check ...For consistency reasons you should<br />actually check whether the single value satisfies the constraint in:<br /><br />> constrain (Ground x) _ = Ground xTom Schrijvershttp://www.blogger.com/profile/05575578560152022579noreply@blogger.comtag:blogger.com,1999:blog-4650294074444534066.post-13999764345382725232011-04-20T02:21:16.552-07:002011-04-20T02:21:16.552-07:00This was a very nice read. Thank you!
As for the ...This was a very nice read. Thank you!<br /><br />As for the exercise for the reader: I didn't use Control.Applicative but Data.Foldable:<br /><br />solve' = filter . (getAll .) . foldMap ((All .) . resolve)Sjoerd Visscherhttp://www.blogger.com/profile/10698430967044536619noreply@blogger.com