Jump to the links to the Grace paper and figs
A long, long time ago in a place far, far away I built a constraint-based graphical editor named Grace. Grace incorporated a PBD (programming by demonstration) component whereby users could "program"/specify/define graphical constraints by demonstrating examples. The method was extremely simple – the user would turn on "watch me" mode and then drag points into the desired relationships and the system would infer the appropriate graphical constraint(s). So, for example, if a user wanted points A and B to enter into a persistent vertical relationship, she would simply drag them into positions that demonstrate such a relationship (that is, into locations such that their respective x-coordinates are approximately equal). Grace would recognize the relationship the user intended and create the appropriate persistent constraint(s) such that (in this example), when A subsequently changed position (was directly dragged, or changed position as the result of another constraint), B would automatically move along with it to maintain the vertical constraint relationship. And vice versa (that is, Grace’s constraints were bi-directional, so that when the user subsequently moved B, A would be moved to the appropriate location to satisfy the constraint).
In terms of Don Norman’s gulf of execution1 (that is, expressing your intentions to the system), the user’s actions are intuitive and very straightforward. When inferring constraints, Grace will only consider as candidate graphical points (points which can be constrained) those that the user has indicated to Grace as being "important" or, in other words, those that the user is "interested in." Then, the user simply shows the system the desired relationship(s) between/among points. Plus the system infers the minimal set of constraint(s) necessary to effect the relationship(s) the user wants; it does so by not inferring redundant or superfluous constraints. By this I mean, not only does Grace not re-infer constraints that already exist per se, but the system will not create a new constraint when it is already in effect as the result of other existing constraints. Well, let me be more concrete; if these constraints exist:
Another reason Grace did not infer
redundant constraints was performance. Grace was implemented (in a very
early version of Smalltalk/V) on a DOS machine (if I remember correctly,
a 33 megahertz 286 or 386 machine – a machine with approximately the power
of a current Palm Pilot). Of course, every time any point is dragged, all
constraints have to be satisfied and possibly many graphical objects have
to be moved and redrawn; thus having fewer constraints made the system
run fast enough to follow the user/mouse.
1 It was a presentation by Allen Cypher
at IBM’s T.J. Watson Research Center that got me re-thinking about Grace
in terms of Norman’s user interaction “gulfs.” Here’s the reference
for the Norman paper:
Norman, D. A. (1986). Cognitive Engineering.
In D. A. Norman & S. W. Draper (Eds.), User Centered System Design
(pp. 31-61). Hillsdale, NJ: LEA.
Here's
a PDF of a paper written in 1991 about Grace. (This is a PDF of a scan
of a hardcopy of the paper! ~2MB)
Here's the reference:
Alpert, S.R. (1993). Graceful interaction
with graphical constraints, IEEE Computer Graphics & Applications,
13(2), 82-91.
Here are PDFs of 3 figures from
the paper (these are clearer than the figs in the PDF file for the full
paper) (full captions/explanations are in the paper).
Fig. 1. Grace's
UI
Fig. 3. Constraints-by-demonstration mode. Also shows the explanation facility.
Fig. 7.Grace's query facility.