Syntax of programs • Expressions are either a variable or nil . • Branching conditions B and commands C are given by B ::= ⋆ | E = E | E � = E C ::= ǫ | x := E ; C | x := E.f ; C | E.f := E ; C | free ( E ); C | x := new (); C | if B then C fi ; C | while B do C od ; C where E ranges over expressions, x over variables, n over field names and j over N . 9/ 27
Syntax of programs • Expressions are either a variable or nil . • Branching conditions B and commands C are given by B ::= ⋆ | E = E | E � = E C ::= ǫ | x := E ; C | x := E.f ; C | E.f := E ; C | free ( E ); C | x := new (); C | if B then C fi ; C | while B do C od ; C where E ranges over expressions, x over variables, n over field names and j over N . • A program is given by fields n 1 , . . . , n k ; C where each n i is a field name and C a command. 9/ 27
Semantics of programs • A program state is either fault or a triple ( C, s, h ), where • C is a command; 10/ 27
Semantics of programs • A program state is either fault or a triple ( C, s, h ), where • C is a command; • s : Var → Val is a stack; 10/ 27
Semantics of programs • A program state is either fault or a triple ( C, s, h ), where • C is a command; • s : Var → Val is a stack; • h : Loc ⇀ fin Val is a heap (we write ◦ for union of disjoint heaps). 10/ 27
Semantics of programs • A program state is either fault or a triple ( C, s, h ), where • C is a command; • s : Var → Val is a stack; • h : Loc ⇀ fin Val is a heap (we write ◦ for union of disjoint heaps). • ( C, s, h ) is called safe if there is no computation sequence ( C, s, h ) � ∗ fault . And ( C, s, h ) ↓ means there is no infinite computation sequence ( C, s, h ) � . . . 10/ 27
Semantics of programs • A program state is either fault or a triple ( C, s, h ), where • C is a command; • s : Var → Val is a stack; • h : Loc ⇀ fin Val is a heap (we write ◦ for union of disjoint heaps). • ( C, s, h ) is called safe if there is no computation sequence ( C, s, h ) � ∗ fault . And ( C, s, h ) ↓ means there is no infinite computation sequence ( C, s, h ) � . . . Proposition (Safety / termination monotonicity) If ( C, s, h ) is safe and h ◦ h ′ defined then ( C, s, h ◦ h ′ ) is safe. If ( C, s, h ) ↓ and h ◦ h ′ defined then ( C, s, h ◦ h ′ ) ↓ . 10/ 27
Preconditions • Formulas F are given by F ::= E = E | E � = E | emp | E �→ E | P E | F ∗ F where P ranges over predicate symbols (of appropriate arity). 11/ 27
Preconditions • Formulas F are given by F ::= E = E | E � = E | emp | E �→ E | P E | F ∗ F where P ranges over predicate symbols (of appropriate arity). • An inductive rule for predicate P is a rule of the form F ⇒ P t 11/ 27
Preconditions • Formulas F are given by F ::= E = E | E � = E | emp | E �→ E | P E | F ∗ F where P ranges over predicate symbols (of appropriate arity). • An inductive rule for predicate P is a rule of the form F ⇒ P t • Semantics given by standard forcing relation s, h | = Φ F 11/ 27
Proof rules • We write proof judgements of the form F ⊢ C where F is a formula and C a command. 12/ 27
Proof rules • We write proof judgements of the form F ⊢ C where F is a formula and C a command. • Symbolic execution rules capture the effect of commands. 12/ 27
Proof rules • We write proof judgements of the form F ⊢ C where F is a formula and C a command. • Symbolic execution rules capture the effect of commands. • E.g., if C is x := E.f ; C ′ , we have the symbolic execution rule: x = E f [ x ′ /x ] ∗ ( F ∗ E �→ E )[ x ′ /x ] ⊢ C ′ | E | ≥ f F ∗ E �→ E ⊢ C 12/ 27
Proof rules • We write proof judgements of the form F ⊢ C where F is a formula and C a command. • Symbolic execution rules capture the effect of commands. • E.g., if C is x := E.f ; C ′ , we have the symbolic execution rule: x = E f [ x ′ /x ] ∗ ( F ∗ E �→ E )[ x ′ /x ] ⊢ C ′ | E | ≥ f F ∗ E �→ E ⊢ C (Here, f ∈ N and E f is the f th element of E . The variable x ′ is a fresh variable used to record the “old value” of x .) 12/ 27
Proof rules (contd.) • We also have logical rules affecting the precondition, e.g.: F ⊢ C Π ′ ⊆ Π (Frame) F ∗ G ⊢ C 13/ 27
Proof rules (contd.) • We also have logical rules affecting the precondition, e.g.: F ⊢ C Π ′ ⊆ Π (Frame) F ∗ G ⊢ C • The inductive rules for a predicate P determine its unfolding rule. 13/ 27
Proof rules (contd.) • We also have logical rules affecting the precondition, e.g.: F ⊢ C Π ′ ⊆ Π (Frame) F ∗ G ⊢ C • The inductive rules for a predicate P determine its unfolding rule. E.g., define “binary tree” predicate bt by x = nil ⇒ bt ( x ) x � = nil ∗ x �→ ( y, z ) ∗ bt ( y ) ∗ bt ( z ) ⇒ bt ( x ) 13/ 27
Proof rules (contd.) • We also have logical rules affecting the precondition, e.g.: F ⊢ C Π ′ ⊆ Π (Frame) F ∗ G ⊢ C • The inductive rules for a predicate P determine its unfolding rule. E.g., define “binary tree” predicate bt by x = nil ⇒ bt ( x ) x � = nil ∗ x �→ ( y, z ) ∗ bt ( y ) ∗ bt ( z ) ⇒ bt ( x ) This gives the unfolding rule: F ∗ u = nil ⊢ C F ∗ u � = nil ∗ u �→ ( y, z ) ∗ bt ( y ) ∗ bt ( z ) ⊢ C F ∗ bt ( u ) ⊢ C 13/ 27
Cyclic proofs • A cyclic pre-proof is a derivation tree with back-links: • • (Axiom) • • • · · · • (Inference) • • 14/ 27
Cyclic proofs • A cyclic pre-proof is a derivation tree with back-links: • • (Axiom) • • • · · · • (Inference) • • • Safety proof condition: there are infinitely many symbolic executions on every infinite path. 14/ 27
Cyclic proofs • A cyclic pre-proof is a derivation tree with back-links: • • (Axiom) • • • · · · • (Inference) • • • Safety proof condition: there are infinitely many symbolic executions on every infinite path. • Termination condition: some inductive predicate is unfolded infinitely often on every infinite path. 14/ 27
Soundness Theorem Fix rule set Φ , and program C , and suppose there is a cyclic proof P of F ⊢ C . Let stack s and heap h satisfy s, h | = Φ F . 15/ 27
Soundness Theorem Fix rule set Φ , and program C , and suppose there is a cyclic proof P of F ⊢ C . Let stack s and heap h satisfy s, h | = Φ F . • If P satisfies the safety condition, ( C, s, h ) is safe; 15/ 27
Soundness Theorem Fix rule set Φ , and program C , and suppose there is a cyclic proof P of F ⊢ C . Let stack s and heap h satisfy s, h | = Φ F . • If P satisfies the safety condition, ( C, s, h ) is safe; • If P satisfies the termination condition, ( C, s, h ) ↓ . 15/ 27
Soundness Theorem Fix rule set Φ , and program C , and suppose there is a cyclic proof P of F ⊢ C . Let stack s and heap h satisfy s, h | = Φ F . • If P satisfies the safety condition, ( C, s, h ) is safe; • If P satisfies the termination condition, ( C, s, h ) ↓ . Proof. Inductive argument over proofs. 15/ 27
Part III Cyclic abduction 16/ 27
Problem statement • Initial problem: Given program C with input variables x , find inductive rules Φ such that P x ⊢ C is valid wrt. Φ. where P is a fresh predicate symbol, and “valid” may have either a safety or a termination interpretation. 17/ 27
Problem statement • Initial problem: Given program C with input variables x , find inductive rules Φ such that P x ⊢ C is valid wrt. Φ. where P is a fresh predicate symbol, and “valid” may have either a safety or a termination interpretation. • General problem: Given inductive rules Φ and subgoal F ⊢ C , find inductive rules Φ ′ such that is valid wrt. Φ ∪ Φ ′ F ⊢ C 17/ 27
Problem statement • Initial problem: Given program C with input variables x , find inductive rules Φ such that P x ⊢ C is valid wrt. Φ. where P is a fresh predicate symbol, and “valid” may have either a safety or a termination interpretation. • General problem: Given inductive rules Φ and subgoal F ⊢ C , find inductive rules Φ ′ such that is valid wrt. Φ ∪ Φ ′ F ⊢ C • Our approach: search for a cyclic safety/termination proof of F ⊢ C , inventing inductive rules as necessary. 17/ 27
Principia abductica (I) Principle I (Proof search priorities) Priority 1: apply axiom rule 18/ 27
Principia abductica (I) Principle I (Proof search priorities) Priority 1: apply axiom rule Priority 2: form backlink 18/ 27
Principia abductica (I) Principle I (Proof search priorities) Priority 1: apply axiom rule Priority 2: form backlink Priority 3: apply symbolic execution 18/ 27
Principia abductica (I) Principle I (Proof search priorities) Priority 1: apply axiom rule Priority 2: form backlink Priority 3: apply symbolic execution Principle II (Guessing things) • In order to serve Priorities 2 and 3 we are allowed to apply logical rules and/or abduce inductive rules. 18/ 27
Principia abductica (I) Principle I (Proof search priorities) Priority 1: apply axiom rule Priority 2: form backlink Priority 3: apply symbolic execution Principle II (Guessing things) • In order to serve Priorities 2 and 3 we are allowed to apply logical rules and/or abduce inductive rules. • We may only abduce rules for undefined predicates. 18/ 27
Principia abductica (I) Principle I (Proof search priorities) Priority 1: apply axiom rule Priority 2: form backlink Priority 3: apply symbolic execution Principle II (Guessing things) • In order to serve Priorities 2 and 3 we are allowed to apply logical rules and/or abduce inductive rules. • We may only abduce rules for undefined predicates. • When we abduce rules for a predicate P in the current subgoal, we immediately unfold that predicate in the subgoal. 18/ 27
Principia abductica (I) Principle I (Proof search priorities) Priority 1: apply axiom rule Priority 2: form backlink Priority 3: apply symbolic execution Principle II (Guessing things) • In order to serve Priorities 2 and 3 we are allowed to apply logical rules and/or abduce inductive rules. • We may only abduce rules for undefined predicates. • When we abduce rules for a predicate P in the current subgoal, we immediately unfold that predicate in the subgoal. (We write A ( P ) for a combined abduction-and-unfold step.) 18/ 27
Principia abductica (II) When forming back-links, we need to avoid: • violating the soundness condition on cyclic proofs; 19/ 27
Principia abductica (II) When forming back-links, we need to avoid: • violating the soundness condition on cyclic proofs; • abducing trivially inconsistent definitions like P x ⇒ P x : P x ⊢ 0 A ( P ) P x ⊢ 0 19/ 27
Principia abductica (II) When forming back-links, we need to avoid: • violating the soundness condition on cyclic proofs; • abducing trivially inconsistent definitions like P x ⇒ P x : P x ⊢ 0 A ( P ) P x ⊢ 0 Principle III (Avoidance tactic) We may not form a backlink yielding an infinite path that violates the safety condition, even if searching for a termination proof. 19/ 27
Principia abductica (II) When forming back-links, we need to avoid: • violating the soundness condition on cyclic proofs; • abducing trivially inconsistent definitions like P x ⇒ P x : P x ⊢ 0 A ( P ) P x ⊢ 0 Principle III (Avoidance tactic) We may not form a backlink yielding an infinite path that violates the safety condition, even if searching for a termination proof. We can use a model checker to enforce Principle III. 19/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { 1 : if ( ⋆ ) 2 : x := x.l 3 : else 4 : x := x.r } 5 : ǫ P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l 3 : else 4 : x := x.r } 5 : ǫ P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l 3 : else 4 : x := x.r } 5 : ǫ x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l 3 : else 4 : x := x.r } 5 : ǫ x = nil ∗ P 1 ( x ) ⊢ 5 while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l 3 : else 4 : x := x.r } 5 : ǫ ǫ x = nil ∗ P 1 ( x ) ⊢ 5 while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l 3 : else 4 : x := x.r } 5 : ǫ ǫ x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l 3 : else 4 : x := x.r } 5 : ǫ x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else 4 : x := x.r } 5 : ǫ x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else 4 : x := x.r } 5 : ǫ x � = nil ∗ ⊢ 2 x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else 4 : x := x.r } 5 : ǫ x � = nil ∗ ⊢ 2 x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else 4 : x := x.r } 5 : ǫ x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x := x.l x � = nil ∗ ⊢ 2 x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } 5 : ǫ x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x := x.l x � = nil ∗ ⊢ 2 x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } 5 : ǫ x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) A ( P 3 ) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x := x.l x � = nil ∗ ⊢ 2 x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } 5 : ǫ P 0 ( x ) ⊢ 0 (Frame) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) A ( P 3 ) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x := x.l x � = nil ∗ ⊢ 2 x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } 5 : ǫ P 0 ( x ) ⊢ 0 (Frame) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) A ( P 3 ) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x := x.l x � = nil ∗ ⊢ 2 x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } 5 : ǫ P 0 ( x ) ⊢ 0 (Frame) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) A ( P 3 ) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x := x.l x � = nil ∗ x � = nil ∗ ⊢ 2 ⊢ 4 x �→ ( y, z ) ∗ P 3 ( x, y, z ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } 5 : ǫ P 0 ( x ) ⊢ 0 (Frame) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) A ( P 3 ) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 3 ( x ′ , y, x ) x := x.l x := x.r x � = nil ∗ x � = nil ∗ ⊢ 2 ⊢ 4 x �→ ( y, z ) ∗ P 3 ( x, y, z ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } 5 : ǫ P 0 ( x ) ⊢ 0 (Frame) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) A ( P 3 ) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 3 ( x ′ , y, x ) x := x.l x := x.r x � = nil ∗ x � = nil ∗ ⊢ 2 ⊢ 4 x �→ ( y, z ) ∗ P 3 ( x, y, z ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } 5 : ǫ P 0 ( x ) ⊢ 0 (Frame) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 0 ( y ) ∗ P 4 ( x ′ , y, x ) A ( P 3 ) ( P 3 ) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 3 ( x ′ , y, x ) x := x.l x := x.r x � = nil ∗ x � = nil ∗ ⊢ 2 ⊢ 4 x �→ ( y, z ) ∗ P 3 ( x, y, z ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } P 0 ( z ) ∗ P 5 ( x, y, z ) ⇒ P 4 ( x, y, z ) 5 : ǫ P 0 ( x ) ⊢ 0 (Frame) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 0 ( y ) ∗ P 4 ( x ′ , y, x ) A ( P 3 ) ( P 3 ) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 3 ( x ′ , y, x ) x := x.l x := x.r x � = nil ∗ x � = nil ∗ ⊢ 2 ⊢ 4 x �→ ( y, z ) ∗ P 3 ( x, y, z ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } P 0 ( z ) ∗ P 5 ( x, y, z ) ⇒ P 4 ( x, y, z ) 5 : ǫ x ′ � = nil ∗ ⊢ 0 x ′ �→ ( y, x ) ∗ P 0 ( y ) ∗ P 0 ( x ) ∗ P 5 ( x ′ , y, x ) P 0 ( x ) ⊢ 0 (Frame) A ( P 4 ) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 0 ( y ) ∗ P 4 ( x ′ , y, x ) A ( P 3 ) ( P 3 ) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 3 ( x ′ , y, x ) x := x.l x := x.r x � = nil ∗ x � = nil ∗ ⊢ 2 ⊢ 4 x �→ ( y, z ) ∗ P 3 ( x, y, z ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } P 0 ( z ) ∗ P 5 ( x, y, z ) ⇒ P 4 ( x, y, z ) 5 : ǫ P 0 ( x ) ⊢ 0 (Frame) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( y, x ) ∗ P 0 ( y ) ∗ P 0 ( x ) ∗ P 5 ( x ′ , y, x ) P 0 ( x ) ⊢ 0 (Frame) A ( P 4 ) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 0 ( y ) ∗ P 4 ( x ′ , y, x ) A ( P 3 ) ( P 3 ) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 3 ( x ′ , y, x ) x := x.l x := x.r x � = nil ∗ x � = nil ∗ ⊢ 2 ⊢ 4 x �→ ( y, z ) ∗ P 3 ( x, y, z ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Worked example: binary tree search 0 : while ( x � = nil ) { x = nil ∗ P 1 ( x ) ⇒ P 0 ( x ) 1 : if ( ⋆ ) x � = nil ∗ P 2 ( x ) ⇒ P 0 ( x ) 2 : x := x.l x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) 3 : else P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) 4 : x := x.r } P 0 ( z ) ∗ P 5 ( x, y, z ) ⇒ P 4 ( x, y, z ) 5 : ǫ P 0 ( x ) ⊢ 0 (Frame) x ′ � = nil ∗ ⊢ 0 x ′ �→ ( y, x ) ∗ P 0 ( y ) ∗ P 0 ( x ) ∗ P 5 ( x ′ , y, x ) P 0 ( x ) ⊢ 0 (Frame) A ( P 4 ) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 0 ( x ) ∗ P 4 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 0 ( y ) ∗ P 4 ( x ′ , y, x ) A ( P 3 ) ( P 3 ) x ′ � = nil ∗ x ′ � = nil ∗ ⊢ 0 ⊢ 0 x ′ �→ ( x, z ) ∗ P 3 ( x ′ , x, z ) x ′ �→ ( y, x ) ∗ P 3 ( x ′ , y, x ) x := x.l x := x.r x � = nil ∗ x � = nil ∗ ⊢ 2 ⊢ 4 x �→ ( y, z ) ∗ P 3 ( x, y, z ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) A ( P 2 ) ( P 2 ) x � = nil ∗ P 2 ( x ) ⊢ 2 x � = nil ∗ P 2 ( x ) ⊢ 4 ǫ if x = nil ∗ P 1 ( x ) ⊢ 5 x � = nil ∗ P 2 ( x ) ⊢ 1 while while x = nil ∗ P 1 ( x ) ⊢ 0 x � = nil ∗ P 2 ( x ) ⊢ 0 A ( P 0 ) P 0 ( x ) ⊢ 0 20/ 27
Simplifying inductive rule sets x = nil : P 1 ( x ) ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) P 0 ( z ) ∗ P 5 ( x, y, z ) ⇒ P 4 ( x, y, z ) 21/ 27
Simplifying inductive rule sets • instantiate undefined predicates to emp ; x = nil : P 1 ( x ) ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) P 0 ( z ) ∗ P 5 ( x, y, z ) ⇒ P 4 ( x, y, z ) 21/ 27
Simplifying inductive rule sets • instantiate undefined predicates to emp ; x = nil : P 1 ( x ) ⇒ P 0 ( x ) x = nil : emp ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) = ⇒ x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) P 0 ( z ) ∗ P 5 ( x, y, z ) ⇒ P 4 ( x, y, z ) P 0 ( z ) ⇒ P 4 ( x, y, z ) 21/ 27
Simplifying inductive rule sets • instantiate undefined predicates to emp ; • eliminate redundant parameters; x = nil : P 1 ( x ) ⇒ P 0 ( x ) x = nil : emp ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) = ⇒ x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) P 0 ( z ) ∗ P 5 ( x, y, z ) ⇒ P 4 ( x, y, z ) P 0 ( z ) ⇒ P 4 ( x, y, z ) 21/ 27
Simplifying inductive rule sets • instantiate undefined predicates to emp ; • eliminate redundant parameters; x = nil : P 1 ( x ) ⇒ P 0 ( x ) x = nil : emp ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) = ⇒ x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) P 0 ( z ) ∗ P 5 ( x, y, z ) ⇒ P 4 ( x, y, z ) P 0 ( z ) ⇒ P 4 ( x, y, z ) ⇓ x = nil : emp ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x �→ ( y, z ) ∗ P 3 ( x, y ) ⇒ P 2 ( x ) P 0 ( y ) ∗ P 4 ( z ) ⇒ P 3 ( x, y ) P 0 ( z ) ⇒ P 4 ( z ) 21/ 27
Simplifying inductive rule sets • instantiate undefined predicates to emp ; • eliminate redundant parameters; • inline single-clause predicates. x = nil : P 1 ( x ) ⇒ P 0 ( x ) x = nil : emp ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) = ⇒ x �→ ( y, z ) ∗ P 3 ( x, y, z ) ⇒ P 2 ( x ) P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) P 0 ( y ) ∗ P 4 ( x, y, z ) ⇒ P 3 ( x, y, z ) P 0 ( z ) ∗ P 5 ( x, y, z ) ⇒ P 4 ( x, y, z ) P 0 ( z ) ⇒ P 4 ( x, y, z ) ⇓ x = nil : emp ⇒ P 0 ( x ) x � = nil : P 2 ( x ) ⇒ P 0 ( x ) x �→ ( y, z ) ∗ P 3 ( x, y ) ⇒ P 2 ( x ) P 0 ( y ) ∗ P 4 ( z ) ⇒ P 3 ( x, y ) P 0 ( z ) ⇒ P 4 ( z ) 21/ 27
Recommend
More recommend