StructureShy Programming SSP Revisited Karl Lieberherr College of
Structure-Shy Programming (SSP) Revisited Karl Lieberherr College of Computer and Information Science / PRL Demeter Research Group Northeastern University, Boston joint work with Ahmed Abdelmeged, Bryan Chadwick and Therapon Skotiniotis U. of Oregon
What is Structure-Shy Programming? • The program consists of modules (e. g. , classes, aspects, functions). • The modules depend on each other’s organization. • A module M 1 is structure-shy with respect to a module M 2 if M 1 refers to a safe organizational abstraction of M 2 and not M 2’s detailed organization. • Attempt generation of correct boilerplate code for M 2 enabled by its safe abstraction. 12/17/2021 U. of Oregon 2
Example • M 1 is structure-shy with respect to M 2 • M 2 = DTD or XML schema or UML class diagram of Company • M 1 = compute average salary: – M 2. traverse(a. Company, from Company to Salary, Summing. Visitor) 12/17/2021 U. of Oregon 3
Example • M 1 is structure-shy with respect to M 2 • M 2 = Java program • M 1 = Aspect. J aspect: before all calls B. g() in the cflow of A. f() execute some code 12/17/2021 U. of Oregon 4
Why do we need a revisit? • XML activity: XML schema and XPath, schema-aware processing • Programming technology should become more structure-shy; leads to more agile programs • SYB: Scrap your boilerplate work – http: //www. cs. vu. nl/boilerplate/ by Ralf Laemmel and Simon Peyton-Jones and others. 12/17/2021 U. of Oregon 5
Why do we need a revisit? • Erik Meijer in LINQ 2. 0: Democratizing the Cloud: Our proposal boils down to separating data models from their query languages and leveraging the fundamental similarities in the operational semantics of each query language. • What are the fundamental similarities? Strategy graphs should be common? 12/17/2021 U. of Oregon 6
In C#: from Erik’s paper from c in Customers where c. City == “Seattle” select new{ c. Name, c. Age } from c in Customers where schema. fetch(c, -> City) == “Seattle” select new{ c. Name, c. Age } 12/17/2021 U. of Oregon 7
Schema-aware XPath High performance XPath • XPath 2. 0 expression: ( element(*, Eq. System)// element(*, Compound)// element(*, Variable) ) 12/17/2021 U. of Oregon 8
Used Variables in Compound eqs Eq. System * lhs Equation rhs ( element(*, Eq. System)// element(*, Compound)// element(*, Variable) rrand lrand Expr ) Simple op Compound Op Add 12/17/2021 … Numerical Times U. of Oregon Integer Variable Ident 9
Used Variables in Compound lhs Equation ( element(*, Eq. System)// element(*, Compound)// element(*, Variable) Expr rrand Some Huge Diagram Without Compound * rhs lrand ge hu eqs Eq. System ) Simple op Compound Op Add 12/17/2021 … Numerical Times U. of Oregon Integer Variable Ident 10
Traversal code class Eq. System { R traverse(…) { R 1 r 1 = eqs. traverse(); R 2 r 2 = huge. traverse(); Based on meta information … ( element(*, Eq. System)// } element(*, Compound)// } element(*, Variable) ) 12/17/2021 U. of Oregon 11
Feedback • Does target guarantee semantics without WYSIWYG make sense (Ralf)? • problems with perobject. Outermost container. • Can we guarantee that target guarantee holds without running the code (based on object invariants? ) 12/17/2021 U. of Oregon 12
Where is this issue relevant? • Whenever Schema/DTD/UML class diagram and XPath used simultaneously – Implementations of XPath • High performance XML – stream filtering – data retrieval » Content Management » Web-Services » XSLT/XQuery Implementation – Adaptive programming tools 12/17/2021 U. of Oregon 13
Schema-aware XPath XML Schema How many traverse methods? 12/17/2021 U. of Oregon 14
Schema-aware XPath • XPath 2. 0 expression: ( element(*, A)// element(*, B 1)// element(*, C 1)// element(*, D) | element(*, A)// element(*, B 2)// element(*, C 2)// element(*, D) )|… 12/17/2021 U. of Oregon 15
XML Schema A-object XPath Expression How many traverse methods? 12/17/2021 U. of Oregon 16
Danger of exponential compilation times 12/17/2021 U. of Oregon 17
Dilemma • Dilemma: USE SCHEMA • YES: danger of huge compilation and run times • NO: danger of huge run times • Solution to dilemma (mid 90 s): Generate a non-deterministic automaton (the cross product of the class graph and strategy graph) and use it to guide the traversal. Leads to both efficient compilation and run-times! 12/17/2021 U. of Oregon 18
XML Schema Adoption & Usage Stan Kitsis Microsoft Corporation • Schemas will play an important role in SOA and WS-*-based technologies. However unless the tools catch up with the ideas behind schemas many opportunities will be missed. • 87% of developers use XML schema through VS • presented in XML 2006 talk • VS can generate schemas from document examples. 12/17/2021 U. of Oregon 19
A Quick Tour of Adaptive Programming • schema. traverse(what. To. Traverse, where. To. Go, what. To. Do); – what. To. Traverse: an object: a. Company – where. To. Go: a graph sg with source s and target t. – what. To. Do: a visitor • semantics: where. To. Go defines an object graph slice of what. To. Traverse. Traversal of object graph slice defines an event sequence that triggers the visitor methods. 12/17/2021 U. of Oregon 20
Design space for Where. To. Go • A general graph (TOPLAS 2004) – includes static XPath 2. 0 expressions (linear graphs and series parallel graphs) – positive and negative information about which nodes and edges to choose • WYSIWYG 12/17/2021 U. of Oregon 21
Design space for What. To. Do • Various forms of visitors • Focus today: – visitors with perobject variables: perobject visitors – functional visitors 12/17/2021 U. of Oregon 22
Design Space Where. To. Go. What. To. Do Combination • Allowing premature terminations • Disallowing premature terminations: target guarantee semantics 12/17/2021 U. of Oregon 23
The big picture for today • Schema: XML, UML, ER • What. To. Do: 1. per-object visitors / functional visitors • Where. To. Go: 2. WYSIWYG • Where. To. Go / What. To. Do: 3. target guarantee semantics • Schema / Where. To. Go: 4. constraints schema. traverse(what. To. Traverse, where. To. Go, what. To. Do); 12/17/2021 U. of Oregon 24
Perobject Visitors • A pattern that is easily implemented in programming languages (if you are willing to write the boilerplate). • A small extension to – our version of structure-shy programming (AP). – DJ, our version of structure-shy programming in plain Java. Adding a @perobject annotation. • A useful extension to the standard Visitor Pattern from GOF. An omission in the standard pattern. 12/17/2021 U. of Oregon 25
Perobject Visitors • They do two things: introduce variables and disseminate them based on traversal-history. • History-based visitors: – ordinary visitor variables make objects available down stream. – perobject variable of class X refer to innermost enclosing object of class X. Done automatically without programmer intervention. 12/17/2021 U. of Oregon 26
Presentation plan for perobject visitors • The idea: small motivating example: the container capacity checking problem – A simplified compilation problem proposed by Mitch Wand. • A slightly larger example: reducing a CNF. 12/17/2021 U. of Oregon 27
Temporary extension during traversal perobject my. Weight: int. 12/17/2021 U. of Oregon 28
At object level: Container capacity 14 items: Item. Pair first: Container capacity 9 items: Item. Pair first: Element weight 3 rest: Item. Pair first: Element weight 7 rest: Empty rest: Item. Pair first: Element weight 3 rest: Empty 12/17/2021 Temporary extension during traversal perobject my. Weight: int. U. of Oregon 29
At object level: Container my. Weight 13 capacity 14 items: Item. Pair first: Container my. Weight 10 capacity 9 items: Item. Pair first: Element weight 3 rest: Item. Pair first: Element weight 7 rest: Empty rest: Item. Pair first: Element weight 3 rest: Empty 12/17/2021 Temporary extension during traversal perobject my. Weight: int. U. of Oregon 30
Boilerplate for perobject public aspect Checker. Visitor. Storage { // The enclosing object of the per object variable my. Weight public int Checker. Visitor. my. Weight = 0; // The current object of the per Object variable my. Weight public int container. Container. my. Weight = 0; pointcut before. Container(Checker. Visitor v, container. Container c): target(v)&& args(c) && execution(public void before(container. Container)) && within(Checker. Visitor); pointcut after. Container(Checker. Visitor v, container. Container c): target(v)&& args(c) && execution(public void after(container. Container)) && within(Checker. Visitor); //. . . 12/17/2021 U. of Oregon 31
More Boilerplate for perobject after-before / before-after /* after finishing the before method of the container just before leaving it to go down and continue the traversal, the current my. Weight of the container is moved to the visitor so that it will be the enclosing container of the next container to be visited. The my. Weight stored in the visitor is stored temporarily in place of the current my. Weight of the container. */ after(Checker. Visitor v, container. Container c): before. Container(v, c){ int tmp = c. my. Weight; c. my. Weight = v. my. Weight; v. my. Weight = tmp; } /* before the after method is invoked on the container. the visitor's my. Weight is restored and the proper value of the my. Weight is captured from the visitor. */ before(Checker. Visitor v, container. Container c): after. Container(v, c){ int tmp = c. my. Weight; c. my. Weight = v. my. Weight; v. my. Weight = tmp; } } 12/17/2021 U. of Oregon 32
my. Weight of innermost enclosing container = my. Weight of parent container Container = capacity: int items: List(Item). Item : Element | Container. Element = weight: int. public class Checker. Visitor extends Visitor { public int total. Violations = 0; // no annotation needed @perobject class Container int my. Weight = 0; public void before(Element e){ my. Weight += e. weight; } small code duplication public void after(Container c){ because of recursion my. Weight += c. my. Weight; boolean vio = c. capacity < c. my. Weight; if(vio){ total. Violations++; } } } traversal from Container to Element 12/17/2021 U. of Oregon 33
Using the visitor Item o = build. Container(); Class. Graph cg = new Class. Graph(container, true, false); Visitor v = new Filter. U(); cg. traverse(o, "from container. Container to container. Element“, v); 12/17/2021 U. of Oregon 34
combines concerns of weight summation, violation predicate and conditional update. public class Checker. Visitor extends Visitor { public int total. Violations = 0; @perobject class Container int my. Weight = 0; public void before(Element e){ my. Weight += e. weight; } public void after(Container c){ my. Weight += c. my. Weight; boolean vio = c. capacity < c. my. Weight; if(vio){ total. Violations++; } } } Let’s separate them. 12/17/2021 U. of Oregon 35
Separate the concerns (using Java) • weight summation Weight. Visitor – Weight. Visitor • violation predicate Vio. Visitor – Vio. Visitor • conditional update Updater – Updater • Counter. U • Filter. U 12/17/2021 Counter. U U. of Oregon Filter. U 36
weight summation Weight. Visitor public class Checker. Visitor extends Visitor { public int total. Violations = 0; @perobject class Container int my. Weight = 0; public void before(Element e){ my. Weight = my. Weight + e. weight; } public void after(Container c){ my. Weight = my. Weight + c. my. Weight; boolean vio = c. capacity < c. my. Weight; if(vio){ total. Violations++; } } } traversal from Container to Element 12/17/2021 U. of Oregon 37
violation predicate public class Vio. Visitor extends Weight. Visitor { @perobject class Container boolean vio; public void after(Container c){ super. after(c); c. vio = c. capacity < c. my. Weight; } } traversal from Container to Element 12/17/2021 U. of Oregon 38
conditional update abstract public class Updater extends Vio. Visitor { public void after(Container c){ super. after(c); if(c. vio){ update(c); } } void update(Container c) {}; } traversal from Container to Element 12/17/2021 U. of Oregon 39
count public class Counter. U extends Updater { public int total. Violations = 0; void update(Container c) { total. Violations++; } } traversal from Container to Element 12/17/2021 U. of Oregon 40
filter public class Filter. U extends Updater { public List violations = new List(); void update(Container c) { violations = new Cons(c, violations); } } traversal from Container to Element 12/17/2021 U. of Oregon 41
Using perobject variables • Need access to enclosing container @perobject class Container int my. Weight = 0; public void before(Element e){ my. Weight += e. weight; } • Need access to current container @perobject class Container boolean vio; public void after(Container c){ super. after(c); c. vio = c. capacity < c. my. Weight; } 12/17/2021 U. of Oregon 42
Asks the question • perobject – perobject current – perobject enclosing • Could be distinguished by compiler: an optimization issue. If no access to enclosing variable, no need to run boilerplate before and after. 12/17/2021 U. of Oregon 43
checking for cyclic objects • need a perobject current variable, called visited, for all objects • need perobject enclosing variable only for certain recursive functions that would need a stack otherwise 12/17/2021 U. of Oregon 44
Using inheritance? • Achieves purpose, but not optimal. public class Updater extends Vio. Visitor { public void after(Container c){ super. after(c); hardwires Container. if(c. vio){update(c); } All that counts is a class C with } per-object variable vio. void update(Container c) {}; } 12/17/2021 Updater requires before/after C with perobject boolean vio U. of Oregon 45
Interfaces match public class Vio. Visitor extends Weight. Visitor { @perobject class Container boolean vio; public void after(Container c){ super. after(c); c. vio = c. capacity < c. my. Weight; } } Vio. Visitor 12/17/2021 provides after C with perobject boolean vio U. of Oregon 46
Benefits of Abstraction: what if we count and filter? Visitor f = new Filter. U(); Visitor c = new Counter. U(); cg. traverse(o, "from container. Container to container. Element“ , new Visitor[]{f, c}); Weight. Visitor Vio. Visitor Updater Counter. U 12/17/2021 U. of Oregon Filter. U 47
Benefits of Abstraction • better modularity • hint for efficiency: the abstraction indicates which computations can be factored out. Weight. Visitor Vio. Visitor Updater Counter. U 12/17/2021 U. of Oregon Filter. U 48
Do both: count and filter equivalent to this tangled code public class Checker. Visitor extends Visitor { public int total. Violations = 0; public List violations = new List(); @perobject class Container int my. Weight = 0; public void before(Element e){ my. Weight += e. weight; } public void after(Container c){ my. Weight += c. my. Weight; boolean vio = c. capacity < c. my. Weight; if(vio){ total. Violations++; violations = new Cons(c, violations); } } 12/17/2021 U. of Oregon 49
Visibility of perobject variables A perobject variable of class C is accessible in all before/after methods of classes that are reachable from C without visiting C again. The variable refers to the innermost C-object visited during the traversal. The implementation uses a local visitor variable that points to the enclosing object. 12/17/2021 U. of Oregon 50
Visibility of perobject variables • A perobject variable of class C is accessible in all before/after methods of classes that are reachable from C without visiting C again or by visiting C and stopping at C. • Special case: per object variable at root: – The scope of a PO variable of class s and strategy sg with source s and target t • nodes(sg with bypassing s on every edge of sg) union • nodes(sub paths of the form “from s to-stop s”) 12/17/2021 U. of Oregon 51
Formula Reduction Visitor Formula = clauses: List(Clause) perobject sats: int perobject unsats: int perobject new. Clauses: List(Clause). Clause = literals: List(Literal) perobject new. Literals: List(Literal). Literal : Pos | Neg common Variable. Pos =. Neg =. Variable = v: int. 12/17/2021 U. of Oregon traversal: from Formula to Literal 52
reduce with respect to l 1 Formula Reduction Visitor • void after (Literal l 2) { reduce(l 1, l 2); } • reduce(l 1, l 2) – reduce(Pos(v), Pos(v)) = true: sats++ – reduce(Neg(v), Neg(v)) = true: sats++ – reduce(Neg(v), Pos(v)) = false: skip l 2 – reduce(Pos(v), Neg(v)) = false: skip l 2 – reduce(l 1, l 2) = l 2 if l 1 and l 2 do not refer to the same variable: add l 2 to new. Literals 12/17/2021 U. of Oregon 53
Formula Reduction Visitor • void after (Clause clause) – if new. Literals is empty: unsats++ else add clause to new. Clauses; 12/17/2021 U. of Oregon 54
The big picture for today • Schema: XML, UML, ER • What. To. Do: 1. per-object visitors / functional visitors • Where. To. Go: 2. WYSIWYG • Where. To. Go / What. To. Do: 3. target guarantee semantics • Schema / Where. To. Go: 4. constraints schema. traverse(what. To. Traverse, where. To. Go, what. To. Do); 12/17/2021 U. of Oregon 55
Functional Visitor for Capacity Checking class Func. Check extends FVisitor{ final int weight, violations; Func. Check(int w, int viol) { weight = w; violations = viol; } Func. Check after(Element e, Func. Check vis){ return new Func. Check(vis. weight+e. weight, vis. violations); } Func. Check after(Container c, Func. Check vis){ return new Func. Check(vis. weight, (vis. violations + ((vis. weight-weight) > c. capacity? 1: 0))); } } 12/17/2021 U. of Oregon 56
Functional Visitor Communication 12/17/2021 U. of Oregon 57
Functional Visitor for Capacity Checking class Func. Check extends FVisitor{ final int weight, violations, myweight; Func. Check(int w, int viol, int myw) { weight = w; violations = viol; myweight = myw; } Func. Check after(Element e, Func. Check vis){ return new Func. Check(vis. weight, vis. violations, vis. myweight + e. weight); } Func. Check after(Container c, Func. Check vis){ return new Func. Check(vis. weight + vis. myweight, (vis. violations + (vis. myweight > c. capacity? 1: 0)), myweight + vis. myweight); } } 12/17/2021 U. of Oregon 58
The big picture for today • Schema: XML, UML, ER • What. To. Do: 1. per-object visitors / functional visitors • Where. To. Go: 2. WYSIWYG • Where. To. Go / What. To. Do: 3. target guarantee semantics • Schema / Where. To. Go: 4. constraints schema. traverse(what. To. Traverse, where. To. Go, what. To. Do); 12/17/2021 U. of Oregon 59
Surprise paths • {A -> B B -> C} • surprise path: A P C Q A B R A S C • eliminate surprise paths: {A->B bypassing {A, B, C} B->C bypassing {A, B, C}} 12/17/2021 U. of Oregon 60
WYSIWYG strategies • Avoid surprise paths • Bypass all classes mentioned in strategy on all edges of the strategy graph • Some users think that WYSIWYG strategies are easier to work with. I am among them. • For WYSIWYG strategies, if class graph has a loop, strategy must have a loop. 12/17/2021 U. of Oregon 61
Strategy Definition • We can view strategies as • • Cs : start node Cd : end node C C : strategy edge Applied to tree objects. 12/17/2021 U. of Oregon 62
What you see is what you get Pure Paths An object path o* satisfies a strategy iff there exists a strategy path p* such that 12/17/2021 U. of Oregon 63
What you see is what you get • Guarantee no surprise nodes in our paths. – Visitor depends on types mentioned in strategy – Semantics guarantee that an edge expands to a path that does not mention any type mentioned in the strategy – Strategies become faithful models of paths in object graphs 12/17/2021 U. of Oregon 64
The big picture for today • Schema: XML, UML, ER • What. To. Do: 1. per-object visitors / functional visitors • Where. To. Go: 2. WYSIWYG • Where. To. Go / What. To. Do: 3. target guarantee semantics • Schema / Where. To. Go: 4. constraints schema. traverse(what. To. Traverse, where. To. Go, what. To. Do); 12/17/2021 U. of Oregon 65
Start walking only if you can make it to the end • Split walking over objects into 2 steps 1) Collect object paths that satisfy the strategy. 12/17/2021 Heap U. of Oregon 66
Start walking only if you can make it to the end • Split walking over objects into 2 steps 1) Collect object paths that satisfy the strategy. 12/17/2021 Heap U. of Oregon 67 Object Graph Slice
Start walking only if you can make it to the end 2) Get the list of paths and expand before and after method bodies before(A) a: A b: B 12/17/2021 x: X c: C y: Y c: C Method call trace Object Graph Slice • Split walking over objects into 2 steps U. of Oregon before(B) before(X) before(Y) before(C) after(Y) after(X) before(C) after(B) after(A) 68
Implementation of target guarantee semantics • Traverse with old semantics. • Store unique path from root. When target is found, activate all the nodes on path: they are in new object graph slice. Visitor will only be executed on activated nodes. • When we hit a node that is activated, we can stop activation: each node is activated only once. • Requires activation bit per node. 12/17/2021 U. of Oregon 69
What did we gain • Strategy exposes – Types the visitor can depend on – Strict sequence of these types in paths • Repeated types are explicit in the strategy (WYSIWYG) • Runtime traversal – Guided form our paths, collect complete object paths – Execute visitor behavior on complete object paths 12/17/2021 U. of Oregon 70
Guarantees to programmers • When you begin traversing, you will get to an object of the target type – Adaptive method gets its fair chance to set up its post-condition/invariant • During traversal, no surprises due to “early” targets • What you see is what you get! Schema-awareness is important for efficiency 12/17/2021 U. of Oregon 71
The big picture for today • Schema: XML, UML, ER • What. To. Do: 1. per-object visitors / functional visitors • Where. To. Go: 2. WYSIWYG • Where. To. Go / What. To. Do: 3. target guarantee semantics • Schema / Where. To. Go: 4. constraints schema. traverse(what. To. Traverse, where. To. Go, what. To. Do); 12/17/2021 U. of Oregon 72
Making SSP safer • Demeter interfaces 12/17/2021 U. of Oregon 73
Writing the strategy for used. Vars • Capture variable references. – Right-hand-side of equation can refer to variable(s). – Strategies are non-empty. – nonempty(gused. Vars) from Equation via ->*, rhs, * to Variable 12/17/2021 U. of Oregon 74
Used Variables. Eq. System Equation rhs lhs rrand lrand Expr Simple op Compound Op Add 12/17/2021 … Numerical Times U. of Oregon Integer Variable Ident 75
Constraints • Define conditions that need to hold on the underlying data structure – Conditions apply to sets of paths. • Constraint primitives. – unique(s) , nonempty(s), – subset(s 1, s 2), equal(s 1, s 2) … • Logical connectives. – && || ! 12/17/2021 U. of Oregon 76
The big picture for today Conclusions • Schema: XML, UML, ER • What. To. Do: 1. per-object visitors / functional visitors • Where. To. Go: 2. WYSIWYG • Where. To. Go / What. To. Do: 3. target guarantee semantics • Schema / Where. To. Go: 4. constraints schema. traverse(what. To. Traverse, where. To. Go, what. To. Do); 12/17/2021 U. of Oregon 77
Conclusions • Structure-shy programming can be improved to facilitate reasoning about structure-shy programs: – – Perobject visitors: more intuitive programs WYSIWYG: no early targets, faithful strategy paths Target guarantee: “complete” path guaranteed constraints: better capture of abstraction, easier schema evolution – Schema-awareness: improve efficiency using techniques from the 90 s. 12/17/2021 U. of Oregon 78
The End • Thank you. 12/17/2021 U. of Oregon 79
possible titles • • transportation visitors scoped introduction visitors per-object variable pattern perobject visitors with per-object fields lambda visitor applicative visitors 12/17/2021 U. of Oregon 80
Container = capacity: int items: List(Item) perobject my. Weight: int. Item : Element | Container. Element = weight: int. 12/17/2021 U. of Oregon 81
XML schema usage • To generate boiler plate code • To optimize XPath evaluation, e. g. , XQuery evaluation • and of course: to verify documents 12/17/2021 U. of Oregon 82
conditional update 1 public class Counter extends Vio. Visitor { public int total. Violations = 0; public void after(Container c){ super. after(c); if(vio){ total. Violations++; } } } traversal from Container to Element 12/17/2021 U. of Oregon 83
conditional update 2 public class Filter extends Vio. Visitor { public int violations = new List(); public void after(Container c){ super. after(c); if(vio){ violations = new Cons(c, violations); } } traversal } from Container to Element 12/17/2021 U. of Oregon 84
Implementation / Visibility • During the traversal of Container c contained inside a Container c 0 we have inside the visitor methods two my. Weight available: this. my. Weight (from enclosing container c 0) and c. my. Weight. • From c: Container bypassing Container to Element determines visibility of c. my. Weight. 12/17/2021 U. of Oregon 85
Visibility • Strategy sg (a general graph) with source s and target t. • perobject variable v at s. Is visible where {sg with “bypassing s” on every edge of sg} visits. • Example: sg = from s via b to t. Visibility is determined by: from s bypassing s via b bypassing s to t. 12/17/2021 U. of Oregon 86
Implementation • We generate Aspect. J aspects to update the perobject variables in the visitor as the traversal enters and leaves the objects where the perobject variable is attached. 12/17/2021 U. of Oregon 87
Type of a Formula • A list of pairs, where the first element, r, of each pair is a relation and the second, f, the number of uses of that relation in the formula. • A relation is given by a pair (p, n) where p is the number of positive literals and n the number of negative literals. 12/17/2021 U. of Oregon 88
Type Construction Visitor Formula = clauses: List(Clause) perobject new. Types: List(Typ). Typ = r: Rel f: int. Rel = p: int n: int. Clause = literals: List(Literal) perobject cr: Rel. Literal : Pos | Neg common Variable. Pos =. Neg =. Variable = v: int. 12/17/2021 U. of Oregon traversal: from Formula to Literal 89
Type Construction Visitor • void before (Formula f) { new. Types = new List(); } • void before (Clause c) {cr. p=0; cr. n=0; } • void after (Pos l 1) { cr. p ++; } • void after (Neg l 1) {cr. n ++; } • void after (Clause c) { new. Types = Cons( new Typ(new Rel(cr. p, cr. n), 1), new. Types); } • void after (Formula f) {consolidate new. Types and return them; } 12/17/2021 U. of Oregon 90
Combined Formula/Type Reduction: Abstract visitor Sat. Unsat • Sat. Unsat : Formula. Reduction | Type. Reduction. Formula = clauses: List(Clause) perobject sats: int. Clause = literals: List(Literal). Literal : Pos | Neg common Variable. Pos =. Neg =. Variable = v: int. 12/17/2021 U. of Oregon 91
Sat. Unsat • after Literal (l 1: assignment, l 2: clause) { reduce(l 1, l 2); } • reduce(l 1, l 2) – reduce(Pos(v), Pos(v)) = true: sats++ – reduce(Neg(v), Neg(v)) = true: sats++ 12/17/2021 U. of Oregon 92
Formula Reduction Visitor • Sat. Unsat : Formula. Reduction | Type. Reduction. Formula = clauses: List(Clause) perobject new. Clauses: List(Clause). Clause = literals: List(Literal) perobject new. Literals: List(Literal). Literal : Pos | Neg common Variable. Pos =. Neg =. Variable = v: int. 12/17/2021 U. of Oregon 93
Type Reduction Visitor Formula = clauses: List(Clause) perobject new. Types: List(Typ). Typ = r: Rel f: Fraction. Rel = p: int n: int. Fraction = v: float. Clause = literals: List(Literal) perobject old_r: Rel perobject new_r: Rel. Literal : Pos | Neg common Variable. Pos =. Neg =. Variable = v: int. 12/17/2021 U. of Oregon traversal: from Formula to Literal 94
Type Reduction Visitor • after Literal (l 1: assignment, l 2: clause) { reduce(l 1, l 2); } • reduce(l 1, l 2) – – – reduce(Pos(v), Pos(v)) = true: sats++ reduce(Neg(v), Neg(v)) = true: sats++ reduce(Neg(v), Pos(v)) = false: skip l 2; old_r. p-reduce(Pos(v), Neg(v)) = false: skip l 2; old_r. n-reduce(l 1, l 2) = l 2 if l 1 and l 2 do not refer to the same variable: add l 2 to new. Literals 12/17/2021 U. of Oregon 95
Type Reduction Visitor • after Clause – if new. Literals is empty: unsats++ else add clause to new. Clauses; 12/17/2021 U. of Oregon 96
More efficient data structure • Use linked list to point to clauses containing a particular variable. 12/17/2021 U. of Oregon 97
Formula = clauses: List(Clause) variables: List(PNVar). perobject sats: int perobject unsats: int. PNVar = Var pos: LList(Clause) neg: LList(Clause). traversal Clause = literals: List(Literal) from Formula perobject new. Literals: List(Literal). via PNVar to Literal : Pos | Neg common Var. Pos =. Neg =. Var = v: int. object level assumptions: from Formula via clauses to c: Clause = from Formula via pn: PNVar via pos to Clause if pn. var appears in c positively. from Formula via clauses to c: Clause = from Formula via pn: PNVar via neg to Clause if pn. var appears in c negatively. 12/17/2021 U. of Oregon after PNVar v 1: sats += length(pos) v 1: delete v from neg v 0: sats += length(neg) v 0: delete v from pos after Clause if host empty unsats++ 98
linked list LList(S) = [next: DLList(S)]. Clause = contained. In: LList(Clause) … 12/17/2021 U. of Oregon 99
Related Work • • Environmental Acquisition (EA) original work by Lorenz and Gil formalization by Cobbe and Felleisen environmental acquisition of objects along containment links 12/17/2021 U. of Oregon 100
EA (Cobbe/Felleisen) class A … { X x; contains Y y; acquires Z z; } Let a be an instance of A. Fields in the first two groups (here, x and y) are parts of a, and fields in the last group (z) are not directly in a but are rather acquired from a’s context. Further, only objects in fields in the second group (here, y) are considered to be contained in a, and therefore only they may acquire fields from a. 12/17/2021 U. of Oregon 101
EA (in our case) class A … { X x; contains Y y; // defined by a strategy acquires Z z; // defined by a strategy } 12/17/2021 U. of Oregon 102
XML Schema Adoption & Usage Stan Kitsis Microsoft Corporation • Schemas will play an important role in SOA and WS-*-based technologies. However unless the tools catch up with the ideas behind schemas many opportunities will be missed. • 87% use XML schema through VS • presented in XML 2006 talk 12/17/2021 U. of Oregon 103
XML schema usage • To generate boiler plate code • To optimize XPath evaluation, e. g. , XQuery expressions • and of course: to verify documents 12/17/2021 U. of Oregon 104
- Slides: 104