Ordering predicate is unsatisfiable - alloy

There seems to be something I don't understand about the first branch of the ordering predicate in ff_next of this alloy model.
open util/ordering[Exposure]
open util/ordering[Tile]
open util/ordering[Point]
sig Exposure {}
sig Tile {}
sig Point {
ex: one Exposure,
tl: one Tile
} fact {
// Uncommenting the line below makes the model unsatisfiable
// Point.ex = Exposure
Point.tl = Tile
}
pred ff_next[p, p': Point] {
(p.tl = last) => (p'.ex = next[p.ex] and p'.tl = first)
else (p'.ex = p.ex and p'.tl = next[p.tl])
}
fact ff_ordering {
first.ex = first
first.tl = first
all p: Point - last | ff_next[p, next[p]]
}
run {}
The intuition here is that I have a number of exposures, each of which I want to perform at a number of tile positions. Think doing panorama images and then stitching them together, but doing this multiple times with different camera settings.
With the noted line commented out the first instance I get is this:
This is equivalent to one pass over the panorama with exposure one, and then dropping the other exposures on the floor.
The issue seems to be the first branch after the => in ff_next but I don't understand what's wrong. That branch is never satisfied, which would move to the next exposure and the start of the panorama. If I uncomment the line Point.ex = Exposure the model becomes unsatisfiable, because it requires that branch.
Any help on why that branch is not satisfiable?

It looks like you're trying to express "every tile must correspond to point with the current exposure before we move to the next exposure." The problem is a major pitfall with ordering: It forces the signature to be exact. If you write
run {} for 6 but 3 Tile, 2 Exposure
Then that works as expected. There are only models when #Point = #Exposure * #Tile. You can write your own reduced version of ordering if this is an issue for you.

Related

Bounding Box intersection

To find elements that are intersecting a geometry I am using the example post by Jeremy in his blog http://thebuildingcoder.typepad.com/blog/2010/12/find-intersecting-elements.html. But the bounding box is always paralell to the axis X, Y and Z and this may cause a problem, like return elements that are not really clashing, because sometimes the bounding box it's not always coincident with the geometry because the family instance is rotated. Besides that, there is the problem that the bounding box will consider the geometry of the symbol and not the instance, and will consider the flipped geometry too, it means that the bounding box is bigger than I am looking for. Is there a way to get the real geometry that are in the currently view ? How can I solve this problem ?
There are many way to address this. Generally, when performing clash detection, you will always run a super fast pre-processing step first to determine candidate elements, and then narrow down the search step by step more precisely in following steps. In this case, you can consider the bounding box intersection the first step, and then perform post-processing afterwards to narrow down the result to your exact goal.
One important question is: does the bounding box really give you all the elements you need, plus more? Are you sure there are none missing?
Once that is settled, all you need to do is add post-processing steps applying the detailed considerations that you care about.
A simple one might be: are all the target element geometry vertices contained in the target volume?
A more complex one might involve retrieving the full solid of the target element and the target volume and performing a Boolean intersection between them to determine completely and exactly whether they intersect, are disjunct, or contained in each other.
Many others are conceivable.
I am using another strategy that is acess the geometry of the instance to verify if the face of the family instace are clashing with a closer conduit.
class FindIntersection
{
public Conduit ConduitRun { get; set; }
public FamilyInstance Jbox { get; set; }
public List<Conduit> GetListOfConduits = new List<Conduit>();
public FindIntersection(FamilyInstance jbox, UIDocument uiDoc)
{
XYZ jboxPoint = (jbox.Location as LocationPoint).Point;
FilteredElementCollector filteredCloserConduits = new FilteredElementCollector(uiDoc.Document);
List<Element> listOfCloserConduit = filteredCloserConduits.OfClass(typeof(Conduit)).ToList().Where(x =>
((x as Conduit).Location as LocationCurve).Curve.GetEndPoint(0).DistanceTo(jboxPoint) < 30 ||
((x as Conduit).Location as LocationCurve).Curve.GetEndPoint(1).DistanceTo(jboxPoint) < 30).ToList();
//getting the location of the box and all conduit around.
Options opt = new Options();
opt.View = uiDoc.ActiveView;
GeometryElement geoEle = jbox.get_Geometry(opt);
//getting the geometry of the element to acess the geometry of the instance.
foreach (GeometryObject geomObje1 in geoEle)
{
GeometryElement geoInstance = (geomObje1 as GeometryInstance).GetInstanceGeometry();
//the geometry of the family instance can be acess by this method that returns a GeometryElement type.
//so we must get the GeometryObject again to acess the Face of the family instance.
if (geoInstance != null)
{
foreach (GeometryObject geomObje2 in geoInstance)
{
Solid geoSolid = geomObje2 as Solid;
if (geoSolid != null)
{
foreach (Face face in geoSolid.Faces)
{
foreach (Element cond in listOfCloserConduit)
{
Conduit con = cond as Conduit;
Curve conCurve = (con.Location as LocationCurve).Curve;
SetComparisonResult set = face.Intersect(conCurve);
if (set.ToString() == "Overlap")
{
//getting the conduit the intersect the box.
GetListOfConduits.Add(con);
}
}
}
}
}
}
}
}
}
Can you please provide a complete minimal reproducible case so we can understand the exact context and analyse what can be done? Maybe you could include one axis-aligned junction box and one that is not, so we can see how ell versus how badly your existing algorithm performs. Thank you!
I summarised this discussion and the results to date in a blog post on filtering for intersecting elements and conduits intersecting a junction box.

Modelling the Chinese Go game

For an university project I'm trying to write the chinese game of Go (http://en.wikipedia.org/wiki/Go_%28game%29) in Alloy. (i'm using the 4.2 version)
I managed to write the base structure. Go's played on a board 9 x 9 wide, but i'm using a smaller set of 3 x 3 for checking it faster.
The board is made of crosses which can either be empty or occupied by black or white stones.
abstract sig Colour {}
one sig White, Black, Empty extends Colour {}
abstract sig Cross {
Status: one Colour,
near: some Cross,
group: lone Group
}
one sig C11, C12, C13,
C21, C22, C23,
C31, C32, C33 extends Cross {}
sig Group {
stones : some Cross,
freedom : some Cross
}
pred closeStones {
near=
C11->C12 + C11->C21 +
C12->C11 + C12->C13 + C12->C22 +
C13->C12 + C13->C23 +
C21->C22 + C21->C11 + C21->C31 +
C22->C21 + C22->C23 + C22->C12 + C22->C32 +
C23->C22 + C23->C13 + C23->C33 +
C31->C32 + C31->C21 +
C32->C31 + C32->C33 + C32->C22 +
C33->C32 + C33->C23
}
fact stones2 {
all g : Group |
all c : Cross |
(c.group=g) iff c in g.stones
}
fact noGroup{
all c : Cross | (c.Status=Empty) iff c.group=none
}
fact groupNearStones {
all disj c,d : Cross |
((d in c.near) and c.Status=d.Status)
iff
d.group=c.group
}
The problem is: following Go rules, every stones must be considered as part of a group. This group is made of all the adiacent stones with the same colour.
My fact "groupNearStones" should be sufficient to describe that condition, but this way I can't get groups made of more of 3 stones.
I've tried rewriting it in different ways, but either the analizer says it found "0 variables" or it groups up all the stones with the same status, regardless of wheter they're near each other or not.
If you could give me any insight I will be grateful, since i'm breaking my head on this simple matter for days.
Ask yourself two questions.
First: in Go, what constitutes a group? You say yourself: it is a set of adjacent stones with the same color. Not that every stone in the group must be adjacent to every other; it suffices for every stone to be adjacent to another stone in the group.
So from a formal point of view: given a stone S, the set of stones in the group as S is the transitive closure of the stones reachable through the relation same_color_and_adjacent, or S.*same_color_and_adjacent.
Second: what constitutes being the same color and adjacent? I think you can define this easily, with what you have.
On a side issue; you may find it easier to scale the model to arbitrary sizes of boards if you reify the notion of rows and columns.
I hope this helps.
[Addendum:] Apparently it doesn't help enough. I'll try to be a bit more explicit, but I want the full solution to come from you and not from me.
Note that the point of defining a relation like same_color_and_adjacent is not to eliminate the formulation of facts or predicates in your model, but to make them easier to write and to write correctly. It's not magic.
Consider first a reformulation of your fact groupNearStones in terms of a single relation that holds for pairs of stones which are adjacent and have the same color. The relation can be defined by modifying your declaration for Cross:
abstract sig Cross {
Status: one Colour,
near: some Cross,
group: lone Group,
near_and_similar : some Cross
}{
near_and_similar = near & { c : Cross | c.#Status = Status}
}
Now your existing fact can be written as:
fact groupNearStones2 {
all disj c,d : Cross |
d in c.near_and_similar
iff
d.group=c.group
}
Actually, I would write both versions of groupNearStones as predicates, not facts. That would allow you to check that the new formulation is really equivalent to the old one by running a check like:
pred GNS_equal_GNS2 {
groupNearStones iff groupNearStones2
}
(I have not run such a check; I'm being a little lazy.)
Now, let us consider the problems you mention:
You never get groups containing more than three stones. Actually, given the formulation of groupNearStones, I'm surprised you get groups with more than two. Consider what groupNearStones says: any two stones in a group are adjacent and have the same color. Draw a board on a piece of paper and draw a group of five stones. Now ask whether such a group satisfies the fact groupNearStones. Say the group is C11, C12, C13, C21, C22. What does groupNearStones say about the pair C21, C13?
Do you see the problem? Are the relations near and 'close enough to be in the same group' really the same? If they are not the same, are they related?
Hint: think about transitive closure.
You never get groups containing a single stone.
How surprising is this, given that groupNearStones says that c.group = d.group only if c and d are disjoint? If you never get single-stone groups, then every stone that should be a single-stone group is not classed as being in any group at all, since such a stone must not satisfy the expression s.group = s.group.
Do you see the problem?
Hint: think about reflexive transitive closure.

Solving maximizing problems in Alloy (or other optimization problems)

I've bought and read the Software Abstractions book (great book actually) a couple of months if not 1.5 years ago. I've read online tutorials and slides on Alloy, etc. Of course, I've also done exercises and a few models of my own. I've even preached for Alloy in some confs. Congrats for Alloy btw!
Now, I am wondering if one can model and solve maximizing problems over integers in Alloy. I don't see how it could be done but I thought asking real experts could give me a more definitive answer.
For instance, say you have a model similar to this:
open util/ordering[State] as states
sig State {
i, j, k: Int
}{
i >= 0
j >= 0
k >= 0
}
pred subi (s, s': State) {
s'.i = minus[s.i, 2]
s'.j = s.j
s'.k = s.k
}
pred subj (s, s': State) {
s'.i = s.i
s'.j = minus[s.j, 1]
s'.k = s.k
}
pred subk (s, s': State) {
s'.i = s.i
s'.j = s.j
s'.k = minus[s.k, 3]
}
pred init (s: State) {
// one example
s.i = 10
s.j = 8
s.k = 17
}
fact traces {
init[states/first]
all s: State - states/last | let s' = states/next[s] |
subi[s, s'] or subj[s, s'] or subk[s, s']
let s = states/last | (s.i > 0 => (s.j = 0 and s.k = 0)) and
(s.j > 0 => (s.i = 0 and s.k = 0)) and
(s.k > 0 => (s.i = 0 and s.j = 0))
}
run {} for 14 State, 6 Int
I could have used Naturals but let's forget it. What if I want the trace which leads to the maximal i, j or k in the last state? Can I constrain it?
Some intuition is telling me I could do it by trial and error, i.e., find one solution and then manually add a constraint in the model for the variable to be stricly greater than the one value I just found, until it is unsatisfiable. But can it be done more elegantly and efficiently?
Thanks!
Fred
EDIT: I realize that for this particular problem, the maximum is easy to find, of course. Keep the maximal value in the initial state as-is and only decrease the other two and you're good. But my point was to illustrate one simple problem to optimize so that it can be applied to harder problems.
Your intuition is right: trial and error is certainly a possible approach, and I use it regularly in similar situations (e.g. to find minimal sets of axioms that entail the properties I want).
Whether it can be done more directly and elegantly depends, I think, on whether a solution to the problem can be represented by an atom or must be a set or other non-atomic object. Given a problem whose solutions will all be atoms of type T, a predicate Solution which is true of atomic solutions to a problem, and a comparison relation gt which holds over atoms of the appropriate type(s), then you can certainly write
pred Maximum[ a : T ] {
Solution[a]
and
all s : T | Solution[s] implies
(gt[a,s] or a = s)
}
run Maximum for 5
Since Alloy is resolutely first-order, you cannot write the equivalent predicate for solutions which involve sets, relations, functions, paths through a graph, etc. (Or rather, you can write them, but the Analyzer cannot analyze them.)
But of course one can also introduce signatures called MySet, MyRelation, etc., so that one has one atom for each set, relation, etc., that one needs in a problem. This sometimes works, but it does run into the difficulty that such problems sometimes need all possible sets, relations, functions, etc., to exist (as in set theory they do), while Alloy will not, in general, create an atom of type MySet for every possible set of objects in univ. Jackson discusses this technique in sections 3.2.3 (see "Is there a loss of expressive power in the restriction to flat relations?"), 5.2.2 "Skolemization", and 5.3 "Unbounded universal quantifiers" of his book, and the discussion has thus far repaid repeated rereadings. (I have penciled in an additional index entry in my copy of the book pointing to these sections, under the heading 'Second-order logic, faking it', so I can find them again when I need them.)
All of that said, however: in section 4.8 of his book, Jackson writes "Integers are not actually very useful. If you think you need them, think again; ... Of course, if you have a heavily numerical problem, you're likely to need integers (and more), but then Alloy is probably not suitable anyway."

Modeling random failures in a connected graph in Alloy

Is it possible to model random failures in Alloy?
For instance, I currently have a connected graph that is passing data at various time steps to its neighbors. What I am trying to do is figure out some method for allowing the model to randomly kill links, and in doing so, still manage to fulfill its goal (of ensuring that all nodes have had their data state set to On).
open util/ordering[Time]
enum Datum{Off, On} // A simple representation of the state of each node
sig Time{state:Node->one Datum} // at each time we have a network state
abstract sig Node{
neighbours:set Node
}
fact {
neighbours = ~neighbours -- symmetric
no iden & neighbours -- no loops
all n : Node | Node in n.*neighbours -- connected
-- all n : Node | (Node - n) in n.neighbours -- comp. connected
}
fact start{// At the start exactly one node has the datum
one n:Node|first.state[n]=On
}
fact simple_change{ // in one time step all neighbours of On nodes become on
all t:Time-last |
let t_on = t.state.On |
next[t].state.On = t_on+t_on.neighbours
}
run {} for 5 Time, 10 Node
The software I'm attempting to model deals in uncertainty. Basically, links between nodes can fail, and the software reroutes along another path. What I'd like to try to do in Alloy is to have some facility for links to 'die' at certain timesteps (preferably randomly). In the top-most fact, I have the capability for the graph to be completely connected, so its possible that, if a link dies, another can possibly pick up the slack (as the simple_change switches the state of the Datum to be On for all connected neighbors).
Edit:
So, I did as was suggested and ran into the following error:
I am confused, as I thought neighbours and Node were still sets?
Here is my updated code:
open util/ordering[Time]
open util/relation
enum Datum{Off, On} // A simple representation of the state of each node
sig Time{
neighbours : Node->Node,
state:Node->one Datum // at each time we have a network state
}{
symmetric[neighbours, Node]
}
abstract sig Node{
neighbours:set Node
}
fact {
neighbours = ~neighbours -- symmetric
no iden & neighbours -- no loops
-- all n : Node | (Node - n) in n.neighbours -- comp. connected
all n : Node | Node in n.*neighbours -- connected
}
// At the start exactly one node has the datum
fact start{
one n:Node|first.state[n]=On
}
// in one time step all neighbours of On nodes become on
fact simple_change{
all t:Time-last |
let t_on = t.state.On |
next[t].state.On = t_on+t_on.neighbours
all t:Time-last | next[t].neighbours in t.neighbours
all t:Time-last | lone t.neighbours - next[t].neighbours
}
run {} for 10 Time, 3 Node
Move the definition of neighbours into Time:
sig Time {neighbours : Node->Node, ....}
You will need to re-express the facts about symmetry etc of neighbours relative to each time point. This is most easily done by doing it in the invariant part of the Time signature:
sig Time {
neighbours : Node->Node,
...
}{
symmetric[neighbours, Node],
....
}
(I do recommend the use of open util/relation to load useful definitions such as symmetric.)
Then the time step simple_change can be complicated by adding in a fact such as
next[t].neighbours in t.neighbours
which can throw away arbitrarily many arcs.
If you want to restrict how many arcs are thrown away in each step you can add a further fact such as
lone t.neighbours - next[t].neighbours
which restricts disposal to at most one arc.

Understanding predicates in alloy

Can someone please help me understand predicates using the following example:
sig Light{}
sig LightState { color: Light -> one Color}
sig Junction {lights: set Light}
fun redLigths(s:LightState) : set Light{ s.color.Red}
pred mostlyRed(s:LightState, j:Junction){
lone j.lights - redLigths(s)
}
I have the below questions about the above code:
1) What happens if the above predicate is true?
2) What happends if it is false?
3) Can someone show me a bit of alloy code that uses the above code and clarifies the meaning of predicates through the code.
I am just trying to understand how do we use the above predicate.
Nothing "happens" until you place a call to a predicate or a function in a command to find an example or counterexample.
First, use the right terminology, nothing 'happens' when a predicate is true; it's the more like the other way around, an instance (an allocation of atoms to sets) satisfies (or doesn't) some condition, making the predicate true (or false).
Also, your model is incomplete, because there is no sig declaration for Color (which should include an attribute called Red).
I assume you want to model a world with crossroads containing traffic lights, if so I would use the following model:
abstract sig Color {}
one sig Red,Yellow,Green extends Color {}
sig Light {
color: Color
}
sig Junction {
lights : set Light
}
// This is just for realism, make sure each light belongs to exactly one junction
fact {
Light = Junction.lights
no x,y:Junction | x!=y and some x.lights & y.lights
}
fun count[j:Junction, c:Color] : Int {
#{x:Light | x in j.lights and x.color=c}
}
pred mostly[j:Junction, c:Color] {
no cc:Color | cc!=c and count[j,cc]>=count[j,c]
}
run{
some j:Junction | mostly[j,Red]
} for 10 Light, 2 Junction, 10 int
Looking at the above, i'm using the # operator to count the number of atoms in a set, and I'm specifying a bitwidth of 10 to integers just so that I don't stumble into an overflow when using the # operator for large sets.
When you execute this, you will get an instance with at least one junction that has mostly red lights, it will be marked as $j in the visualizer.
Hope this helps.
sig Light{}
sig LightState { color: Light -> one Color}
sig Junction {lights: set Light}
fun redLigths(s:LightState) : set Light{ s.color.Red}
pred mostlyRed(s:LightState, j:Junction){
lone j.lights - redLigths(s)
}
What the predicate simply means in the example you gave is;
The difference between the set A, in this case the relation (j.lights) and another set say B, returned from the function redligths, of which the Predicate will always constraint the constraint analyser to return only red light when you run the Predicate "mostlyRed".
And note that the multiplicity "lone" you added to the predicate's body only evaluate after the difference between the set A and B (as I assumed) has been evaluated, to make sure that at most one atom of red is returned. I hope my explanation was helpful. I will welcome positive criticism. Thanks

Resources