230 likes | 375 Views
Policy Enforcement and Refinement. Douglas R. Smith Kestrel Institute Palo Alto, California. E ↦ Int le ↦ axioms ↦ thms. Specification morphism: a language translation that preserves provability. Specifications and Morphisms. spec Partial-Order is sort E
E N D
Policy EnforcementandRefinement Douglas R. Smith Kestrel Institute Palo Alto, California
E ↦ Int le ↦ axioms ↦ thms Specification morphism: a language translation that preserves provability Specifications and Morphisms spec Partial-Order is sort E op le: E, E Boolean axiom reflx is le(x,x) axiom trans is le(x,y) le(y,z) le(x,z) axiom antis is le(x,y) le(y,x) x = y end-spec spec Integer is sort Int op : Int, Int Boolean op 0 : Int op _+_ : Int , Int Int … end-spec
1. Library of Refinements Global Search Global Search Resource Set po Global Search Algorithm Scheduling1 Set Transportation Resource Global Search Algorithm Sequence po Scheduling2 Sequence 2. Library of Refinement Generators • Rewrite Simplification • Context-dependent Simplification • Finite Differencing • Case Analysis • Partial Evaluation Scheduling3 Scheduling4 Constructing Refinements Scheduling0 Context-dependent Simplification Finite Differencing
Issue: How to Handle Nonfunctional and Cross-Cutting Concerns wrtComposition and Refinement? A concern is cross-cutting if its manifestation cuts across the dominant hierarchical structure of a program/system. • Examples • Log all errors that arise during system execution • Enforce a system-wide error-handling policy • Disallow unauthorized data accesses • Enforce timing and resource constraints on a system design
Policy Conditions Refined System Policy Constraint Working Hypothesis • A policy is a cross-cutting constraint that reduces nondeterminism in a system. • Policy enforcement determines a refinement. • We can express policies constraint as automata or in temporal logic • Explore enforcement mechanisms for various classes of policies showing where the policy applies seems to require sound static analysis System
A Generative Approach to Aspect-Oriented Programming hypothesis: aspects are invariants to maintain
Maintain an Error Log Policy: Maintain an error log in a system
hist :=S0, act0 hist := hist ::S1, act1 hist := hist ::S2, act2 Virtual Variables in State key idea: extend state with a virtual history variable act0 act1 act2 S0 S3 ••• S1 S2 • Virtual variables • exist for purposes of specification • sliced away prior to code generation
Maintain an Error Log Policy: Maintain an error log in a system Invariant: errlog = filter(error?, actions(hist)) Disruptive Actions: error?(act) Spec for Maintenance Code : for each error action erract, Assume: errlog = filter(error?, actions(hist)) Achieve: errlog´ = filter(error?, actions(hist´)) = filter(error?, actions(hist :: S, erract)) = filter(error?, actions(hist):: erract) = filter(error?, actions(hist)):: erract = errlog :: erract spec satisfied by: errlog :=errlog :: erract
Maintaining an Error Log act0 error1 act2 S0 S3 ••• S1 S2 hist :=S0, act0 hist := hist ::S1, act1 hist := hist ::S2, act2 errlog :=errlog errlog :=errlog::error1 errlog :=errlog
General Case • Invariant: I(x) • Disruptive Actions: any action that changes x or an alias • Spec for Maintenance Code : • for each such action act with specification • Assume: P(x) • Achieve: Q(x, x´) • generate and satisfy new specification • Assume: P(x) I(x) • Achieve: Q(x, x´) I(x´) spec typically satisfied by code of the form: act || update
Error-Handling Policiesand their Enforcement Douglas R. Smith Klaus Havelund Kestrel Technology/NASA Ames Palo Alto, California www.kestreltechnology.com
NonRobust Java Program class AddNumbersFromFile { static void doIt(String fileName) throws IOException { DataInputStream source = null; if (fileName != null) source = new DataInputStream(new FileInputStream(fileName)); int count = source.readInt(); int sum = addEm(source,count); System.out.println("Sum is " + sum); } static int addEm(DataInputStream s, int c) throws IOException { int sum = 0; for (int i = 0; i < c; i++) sum += s.readInt(); if (s.available() == 0) s.close(); return sum; }}
Generic File Management Policy FileNotFoundException / handler1 IOException / handler2 use open close Start Open Stop use Error handler3
Policy Simulation on the Example Program DoIt entry addEm entry {Start} T fileName != null {Open} F sum = 0; i= 0; source = new DataInputStreamPolicy(fileName) {Start} {Open} {Open} ambiguous analysis F T i < c {Start,Open} {Open} count = source.readInteger(); sum += source.readInteger(); i++; {Open} {Open} call addEm(source,count); {Open Closed, Open Open } {Open} T s.available()==0 {Open} sum = result F s.close(); {Open,Closed} {Open} {Closed} System.out.println("Sum is " + sum) {Open, Closed} {Open,Closed} return sum exit {Open, Closed} exit
Program Transformation to Reduce Policy Ambiguity has ambiguous analysis if ( fileName != null ) source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt(); distribute if-then-else over semicolon if ( fileName != null ){ source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt(); } else { count = source.readInt(); } has unambiguous analysis! apply the policy and simplify if ( fileName == null ) throw new Error("Attempt to read from an unopen File"); source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt(); unambiguous analysis, clear code
Revised Java Program with Unambiguous Analysis class AddNumbersFromFile { static void doIt(String fileName) throws IOException { DataInputStream source = null; if ( fileName == null ) {throw new Error("Attempt to read from an unopen File");} source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt(); int sum = addEm(source,count); System.out.println("Sum is " + sum); } static int addEm(DataInputStream s, int c) throws IOException { int sum = 0; for (int i = 0; i < c; i++) sum += s.readInt(); // if (s.available()==0) s.close(); return sum; } }
Revised Java Program with Enforced Policy class RobustlyAddNumbersFromFile1 { static void doIt(String fileName) throws IOException{ DataInputStreamForAddNumbers1 source = null; if(fileName==null){ throw new Error("Attempt to read from an unopen File"); } try { source = new DataInputStreamForAddNumbers1(fileName); } catch (FileNotFoundException e) { throw new Error("File " + fileName + " cannot be found"); } int count = 0; try { count = source.readInt(); } catch(EOFException e){ source.close(); throw new Error("File " + source.filename + " contains no data!"); } catch(IOException e){ source.close(); throw new Error("Bad data in file" + source.filename); } …
Ambiguous Analysis If the analysis remains ambiguous, then some form of runtime tracking of state is required, and runtime enforcement decisions. Technique: use subclassing to track state
Generic File Management Policy FileNotFoundException / handler1 IOException / handler2 use open close Start Open Stop use Error handler3
Ambiguous Analysis public class DataInputStreamForAddNumbers extends DataInputStream { public static final int Start = 1; public static final int Open = 2; public static final int Closed = 3; int currentState = Start; public String filename; public DataInputStreamForAddNumbers(String filename) throws FileNotFoundException { super(new FileInputStream(filename)); // field in stores the file handle this.filename = filename; this.currentState = Open; } public boolean inState(int state){ return this.currentState == state; }
Ambiguous Analysis public int readInteger() throws IOException { int x = 0; switch(currentState){ case Start: throw new Error("Attempt to read from an unopen File"); case Open: try{ x = super.readInt(); } catch (EOFException e){ throw new EOFException("File" + filename + "contains no data!"); } catch (IOException e){ throw new IOException("Cannot read from file " + filename); } break; case Closed: throw new Error("File " + filename + "already closed"); } return x; }