accumulating using BEFORE

1 view
Skip to first unread message

Jim Steel

unread,
Mar 3, 2011, 12:46:01 AM3/3/11
to tef...@googlegroups.com
I'm having a problem to do with ordering. Its a real problem, to do with placing adjacent rectangles in a 2-dimensional space, but I'll try to distill it here to a simpler abstract problem.

Imagine that my source model is an ordered collection of objects with an integer-valued property "val", and I want to transform this into a collection of objects with an integer-valued property "cumVal", whose value is equal to the sum of all the preceding objects' "val" values (does that make sense?).

The problem I'm having is that I can't see how to do this using the BEFORE constraint, which can only constrain partial orders within a collection, not total orders. I can find the first value easily enough, doing something like 

PATTERN cumVal(srcContainer, srcElement, cumVal)
WHERE IF NOT (el2 BEFORE srcElement IN srcContainer.contents)
          THEN cumVal = 0

but I can't see how to do the rest.

Any tips?

Jim.

michael lawley

unread,
Mar 3, 2011, 6:09:09 AM3/3/11
to tef...@googlegroups.com

Hi Jim,

The best way to approach this sort of thing in Tefkat is to use PATTERNs to spell out the constraints of specific parts of the problem. In this case, what you want is to be able to find are elements in the ordered collection that are adjacent rather than just ordered. That is, the elements for which there is no intervening element. I think of this as edges between nodes rather than paths, which leads to the first two patterns below. The next two round out the solution (caveat - untested, and it's a long time since I've written any real Tefkat rules :-)

Note a basic trick here - the use of a PATTERN (path) to get the quantification on "x" the right way round.  If we'd just used a single rule, then the quantification on "x" would have been 'EXISTS x NOT' (rather than 'NOT EXISTS x'), not only leaving "x" unbound (i.e., no set of objects to range over), but also with the wrong quantification (should be 'ALL x WHERE s.contents = x NOT')

Cheers,

michael

PATTERN edge(s, o1, o2)
WHERE o1 BEFORE o2 IN s.contents
  AND NOT path(s, o1, o2)
;

PATTERN path(s, o1, o2)
WHERE o1 BEFORE x IN s.contents
  AND x BEFORE o2 IN s.contents
;

PATTERN objVal(s, o, v)
WHERE s.contents = o
  AND o.val = v
;

PATTERN sumObjVal(s, o, sum)
WHERE objVal(s, o, v)
  AND
    IF edge(s, o, o1) THEN
      sumObjVal(s, o1, v1)  AND sum = v1 + v
    ELSE
      sum = v
    ENDIF
;

--
You received this message because you are subscribed to the Google Groups "Tefkat" group.
To post to this group, send an email to tef...@googlegroups.com.
To unsubscribe from this group, send email to tefkat+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/tefkat?hl=en-GB.

Reply all
Reply to author
Forward
0 new messages