From: Andreas Launila Date: 2007-06-06T23:55:31+09:00 Subject: Re: Gecode/R - Request for syntax feedback James Edward Gray II wrote: > On Jun 6, 2007, at 5:21 AM, Andreas Launila wrote: >> As an example there's a domain >> constraint which basically says that x must be in a given range. >> Negating the constraint is possible and might be written as follows. >> >> constrain x.in(1..17) >> constrain x.not_in(1..17) > > This seems like a very viable solution to me. If it's possible to just > negate all of the tests, that should work: > > equal/not_equal > in/not_in > includes/does_not_include > Yes, that could work. I was probably locking myself in a bit too much trying to make everything read as must/must_not. I will sketch how other constraints could be expressed on a similar form to see if there are any consistency problems. There doesn't exist support for negating all constraints. One example is a sorting constraint, which basically says that some variables, when sorted, are equal to some other variables. Which could be expressed something like: constrain xs.sorted.equal(ys) or constrain sorted(xs).equal(ys) or constrain sort(xs).equal(ys) The last couple avoid having to modify Enumerable. Using this form I prefer the second version. The point however is that there's no simple way to negate that constraint using Gecode, beyond hacking together several constraints that express that a single element is out of order and saying that at least one of them must hold. To me it would seem accepatable to simply throw an exception in those cases (or translate it to something inefficient behind the scenes, but I would rather not do that). >>>> === Overall syntax === >>>> >>>> Every model has at least three parts: >>>> * Declaration of variables (in the example that would be "squares = >>>> ...") >>>> * Definition of constraints (all the lines from "all_distinct ..." down >>>> to "squares.diagonal..." in the example). >>>> * Selection of branching strategy (the line starting with >>>> "branch_on" in >>>> the example) >>>> >>>> Maybe that could be used to produce some other overall syntax? E.g. >>>> something other than throwing it all into a constructor. >>> >>> Reading this definitely made me wonder over a DSL. That's pretty much >>> what you have with the class system though. If constrain() becomes the >>> constraint definer and branch_on() represents the branching strategy, >>> the only thing you haven't really wrapped is the variable declaration. >>> >>> I don't know what that would look like, but maybe something like: >>> >>> variable :some_name, :int, accepted_range_of_values >>> >>> Then I guess you could later refer to them by name. Of course, that's >>> just not as convenient when it comes to accessing them. Iterating over >>> rows and columns shows this well. >> >> I don't understand the part about not being as convenient to access. I'm >> assuming that one could define matrices just as well as single variables >> with such a syntax, which would basically give the same level of >> convenience. An example to see if I understood you correctly (possibly >> with some keys for the parameters beyond the name and type): >> >> class MagicSquare < Gecode::Model >> def initialize(n) >> variable :squares, :int_matrix, n, n, 1..(n**2) >> squares.row(0) >> ... >> end >> end > > I think this makes it more complicated to support custom data > structures. What if I want a MyUniqueDataStructure full of IntVars, for > example? > True, I didn't think about custom data structures. -- Andreas Launila