No Slide Title

Download Report

Transcript No Slide Title

Policy Enforcement
and
Refinement
Douglas R. Smith
Kestrel Institute
Palo Alto, California
Kestrel
Specifications and Morphisms
spec Partial-Order is
E ↦ Int
sort E
le ↦ 
op le: E, E  Boolean
axioms ↦ thms
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
Specification morphism: a language translation that preserves provability
Kestrel
Constructing Refinements
1. Library of Refinements
Global
Search
Global Search
Algorithm
Scheduling0
Resource
Set
Sequence
Global
Search
Transportation
Resource
Global Search
Algorithm
po
Scheduling1
po
Scheduling2
2. Library of Refinement Generators
• Rewrite Simplification
• Context-dependent Simplification
• Finite Differencing
• Case Analysis
• Partial Evaluation
Sequence
Context-dependent
Simplification
Scheduling3
Finite Differencing
Scheduling4
Kestrel
Set
Issue: How to Handle Nonfunctional and
Cross-Cutting Concerns wrt
Composition 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
Kestrel
Working Hypothesis
1.
A policy is a cross-cutting constraint that reduces nondeterminism in a system.
2.
Policy enforcement determines a refinement.
3.
We can express policies constraint as automata or in temporal logic
4.
Explore enforcement mechanisms for various classes of policies
Policy Conditions
System
Policy Constraint
Refined
System
Kestrel
showing where the
policy applies seems to
require sound static
analysis
A Generative Approach
to
Aspect-Oriented Programming
hypothesis: aspects are invariants to maintain
Kestrel
Maintain an Error Log
Policy: Maintain an error log in a system
Kestrel
Virtual Variables in State
key idea: extend state with a virtual history variable
S0
act0
hist := S0, act0
S1
act1
hist := hist ::S1, act1
S2
act2
hist := hist ::S2, act2
Virtual variables
• exist for purposes of specification
• sliced away prior to code generation
Kestrel
S3
•••
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
Kestrel
Maintaining an Error Log
S0
act0
hist := S0, act0
errlog := errlog
Kestrel
S1
error1
hist := hist ::S1, act1
errlog := errlog::error1
S2
act2
hist := hist ::S2, act2
errlog := errlog
S3
•••
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
Kestrel
Error-Handling Policies
and their Enforcement
Douglas R. Smith
Klaus Havelund
Kestrel Technology/NASA Ames
Palo Alto, California
www.kestreltechnology.com
Kestrel
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;
}}
Kestrel
Generic File Management Policy
FileNotFoundException / handler1
IOException / handler2
use
open
Start
close
Open
use
Stop
Error
handler3
Kestrel
Policy Simulation on the Example Program
DoIt entry
addEm entry
{Start}
fileName != null
T
{Open}
F
{Start}
sum = 0;
i= 0;
source = new DataInputStreamPolicy(fileName)
{Open}
ambiguous
analysis
{Open}
F
{Start,Open}
T
i<c
{Open}
count = source.readInteger();
sum += source.readInteger();
i++;
{Open}
{Open}
call addEm(source,count);
{Open  Closed,
Open  Open }
{Open}
s.available()==0
sum = result
{Open,Closed}
T
{Open}
F
s.close();
{Open}
{Closed}
System.out.println("Sum is " + sum)
{Open, Closed}
{Open,Closed}
exit
return sum
{Open, Closed}
exit
Kestrel
Program Transformation to Reduce Policy Ambiguity
if ( fileName != null )
source = new DataInputStream(new FileInputStream(fileName));
count = source.readInt();
has
ambiguous
analysis
distribute if-then-else over semicolon
if ( fileName != null ){
source = new DataInputStream(new FileInputStream(fileName));
has
count = source.readInt();
unambiguous
} else {
analysis!
count = source.readInt();
}
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();
Kestrel
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;
}
}
Kestrel
Revised Java Program with Enforced Policy
class RobustlyAddNumbersFromFile1 {
Kestrel
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
Kestrel
Generic File Management Policy
FileNotFoundException / handler1
IOException / handler2
use
open
Start
close
Open
use
Stop
Error
handler3
Kestrel
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;
}
Kestrel
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;
}
Kestrel
Extra slides
Kestrel