Branch of Russian Academy of Sciences, Novosibirsk, Russia. Theoretical Programming Lab.: Prof. Valery Nepomnyaschy, Prof. Nikolay Shilov, Igor Anureev, Alexey Promsky, Ilya Maryasov, Dmitry Kondratyev, ... Studies of theoretical foundations of informatics which can be applied in practical tasks such as modeling of sequential and parallel processes; semantics and specication; program verication The C program verication is one of our high-priority goals.
TIOBE index) Basis for the kindred languages: (1), (3) and (4). Can we work with them if we are unable to verify the C programs? Esp. when not all problems of the C program verication are solved. The interest in the C program verication is conrmed by researchers: VERISOFT, WHY (Frama-C), VCC
the founders say? Restrictions that contribute to provability are what make a programming language good. C.A.R. Hoare. The C-light language covers a major part of the C99 (C0 completely, Misra C almost); sets the evaluation order; avoids some low-level features. The C-kernel language possesses light and sound axiomatic semantics. Easy addition of new/remaining constructions? This is exactly what our research serves for!
some challenges from the well-known collections: aliasing, abrupt termination, side-eects, function pointers. Specications and verication of a subset of the Standard C Library /*@ requires \valid_range(s1, 0, strlen(s2)) && valid_string(s2); assigns s1[0..strlen(s2)]; ensures strcmp(s1, s2) == 0 && \result == s1; ensures \base_addr(\result) == \base_addr(s1); */ char *strcpy(char *restrict s1, const char *restrict s2) Experiments on self-applicability. Our translator from C-light into C-kernel is implemented using Clang (C++ API), however, a good part of its functionality is expressible in C-light.
axiomatic semantics of a language takes form of Verication Condition Generator (VCG), thus reducing the question of program correctness to the truth of lemmas (verication conditions VCs) in some applied theory. We would like to add easily and correctly new axioms and rules to our Hoare systems and, consequently, to VCG. The reasons: The complete C language or transition to C++. No doubts here. The context specic rules or even specialized VCGs. Not so obvious. Some examples are required.
the following pattern was found swap(x, y, buf ) ≡ memcpy(buf, x, m); memcpy(x, y, m); memcpy(y, buf, m); The general rule for the function call looks like {P } f (x) {Q } P ⇒ (P α ∧ Q γ ⇒ Qγβ) {P} f (e); {Q} , The substitutions α, β model the argument passing, whereas γ renames the variables and, thus, is equivalent to quantication. In the meantime, we can enrich the Hoare system by the following axiom: {x = x 0 ∧ y = y 0 } swap(x, y, buf ) {x = y 0 ∧ y = x 0 }
two-dimensional matrix and e(k, i) is an expression depending on matrix indices k and i, consider the following triple: {Q(M ← rep(M, mat(e 1 , e 2 , e 3 , e 4 ), e(s, t)))} for(k = e 1 ; k <= e 2 ; k++) for(i = e 3 ; i <= e 4 ; i++) M[k][i] = e(k, i); {Q} where matrix rep(M, mat(e 1 , e 2 , e 3 , e 4 ), e(s, t))) results from replacement of all elements corresponding to sub-matrix mat(e 1 , e 2 , e 3 , e 4 ) by expression e. All these logical functions (rep, mat, etc) are dened by a set of axioms. For example rep(rep(M, S 1 , e(s, t)), S 2 , e(s, t)) = rep(M, S 1 ∪ S 2 , e(s, t))
loop invariant elimination we can step to 1. program schemata. For example, Dijkstra's linear search scheme {P} d = d 0 ; while(prop(d)) d = f (d) {Q} where d, d 0 , prop, f are uninterpreted objects and Q : ¬prop(dk) ∧ ∀i(0 ≤ i ≤ k ⇒ prop(di )) ∧ d = dk and di = f (di−1 ) 2. and even further to program transformations {P} A {P} {P} B {Q} £ {P} A; B {Q} inv ≡ P {P} if(e) A {P} £ {P} {inv}while(e) A {P}
are being conducted in our Lab: Ilya Maryasov develops the Mixed-semantics approach; Prof. Valery Nepomnyaschy develops the approach of Finite iterations over data structures; Prof. Nikolay Shilov tries to apply the program schemata to verication of dynamic programming algorithms. Two possible ways: One huge VCG replenished by rules every time we apply to a new domain hardly a good idea. A collection of specialized VCGs much better. Finally, the error-prone process of manual implementation of VCG can compromise the verication. A possible solution the MetaVCG approach.
not only by testing/verication but also by its construction? Basing on classical results by E.W. Dijkstra, R.L. London, D.C. Luckham etc., M. Moriconi and R. Schwartz proposed in 1981 a method for mechanically constructing VCGs from a useful class of Hoare logics. Any VCG constructed by the method is shown to be sound and deduction-complete w.r.t the associated Hoare logic.
formulas (P, P ∧ x = 5, or x = 5). For a Hoare triple of the form {P(P 1 , ..., Pm)} S {Q(Q 1 , ..., Qn)} where predicate symbols Pi and Qj are logically free in P and Q, respectively, we have Pi ⇐ Qj , for i ∈ {1, ..., m} and j ∈ {1, ..., n} Given H + ⇐ T, H will be called the head of the dependency chain and T the tail. For a rule of the form {P 1 } S 1 {Q 1 }, ..., {Pn} Sn {Qn}, Γ {P} S {Q} we have S Si , for i ∈ {l, ..., n} ( +).
predicate symbols in a formula, a Hoare triple or a rule. Function FragVars denotes the set of "fragment variables" in the language fragment S of a Hoare triple {P} S {Q}. FragVars(if B then S 1 else S 2 fi) = {B, S 1 , S 2 } We use FreePreds and FragVars to distinguish those logically free variables that are bound in the program fragment when a rule is applied from those that must be bound by wp-calculus.
instance N of {P 1 } S 1 {Q 1 } , ..., {Pn} Sn {Qn}, Γ {P} S {Q} that satises the following constraints: 1. P 1 ,..., Pn and Q are predicate symbols free in N. 2. Γ is a sentence in the underlying theory such that FreePreds(Γ) ⊆ FreePreds(N) ∪ FragVars(S). 3. The fragment variables of each Si must be bound in S. So ∪ 1≤i≤nFragVars(Si ) ⊆ FragVars(S).
of N must satisfy two dependency constraints. a. Pi + ⇐ Pj ⊃ i < j b. T + ⇐ U ∧ ¬(∃R)U + ⇐ R ⊃ U ≡ Q ∨ U bound in N 5. Monotonicity. Let P[P ← false, P ∈ s] denote P with the proper substitution of false for each predicate P in the set s. Then P[P 1 , ..., Pn, Q ← true] ∨ ∀s ⊆ {P 1 , ..., Pn, Q} ¬P[P ← false, P ∈ s] This constraint must hold for Γ and for each Qi .
the form {P 1 } S 1 {Q 1 }, ..., {Pn} Sn {Qn}, Γ {P} S {Q} wdp can be dened as follows: wdp(S, Q) = P[P 1 ← wdp(S 1 , Q 1 ), ..., Pn ← wdp(Sn, Qn)]∧ (∀v)Γ[P 1 ← wdp(S 1 , Q 1 ), ..., Pn ← wdp(Sn, Qn)] where [P 1 ← t 1 , ..., Pn ← tn] denotes n proper substitutions carried out sequentially in a left-to-right order, and v is the set of all free logical variables in Γ.
{P 1 } S 1 {Q}, {P 2 } S 2 {Q} {B ⊃ P 1 ∧ ¬B ⊃ P 2 } if B then S 1 else S 2 fi {Q} {P 1 } S {P}, P ∧ ¬B ⊃ Q, P ∧ B ⊃ P 1 {P} while B inv P do S od {Q} Moreover, the order on the premises is required, thus, narrowing the class of applicable Hoare systems. By the way, the axiomatic semantics of the C-kernel language does not satisfy these requirements. Perhaps, we could weaken the constraints somehow?
instance G of I 1 , ..., In, Γ {P} S {Q} that satises normal form constraints 1-3 and 4b, where: 1. Each premise I is in one of the following forms a. {R} S {Q} b. {F} S {Q} c. {R ∧ F} S {Q} where, in all three cases, R is a metavariable evaluating to a single predicate symbol free in G, F is a metavariable evaluating to a formula not containing any predicate symbols free in G, and Q is a metavariable.
irreexive with respect to I 1 , ..., In. 3. Let r be the set of predicate symbols free in the preconditions of I 1 , ..., In. Then, the following constraint on P must hold: P[P ← true, P ∈ r ∪ {Q}]∧ ∀s ⊆ r ∪ {Q}¬P[P ← false, P ∈ s] This constraint must hold for Γ and for each Qi . {P ∧ B} S {P}, P ∧ ¬B ⊃ Q {P} while B inv P do S od {Q} {P ∧ B} S1 {Q}, {P ∧ ¬B} S2 {Q} {P} if B then S1 else S2 fi {Q}
to the three classes of allowable premises, yielding a schema of the form {F 1 } S 1 {Q 1 }, ..., {Fj } Sj {Qj }, {Bj+1 } Sj+1 {Qj+1 }, ..., {Bk} Sk {Qk}, {Bk+1 ∧ Fk+1 } Sk+1 {Qk+1 }, ..., {Bn ∧ Fn} Sn {Qn}, Γ {P} S {Q} We now dene two functions: 1. Duplicates(i) = {m : |Bm| = |Bi |, j + 1 ≤ m ≤ n}, for j + 1 ≤ i ≤ n where, for a metavariable B, |B| denotes the partially interpreted rst-order formula bound to B, and 2. MkFormula(i) = Pi , for j + 1 ≤ i ≤ k |F| ⊃ Pi , for k + 1 ≤ i ≤ n
above as {P 1 } S 1 {Q 1 }, ..., {Pn} Sn {Qn}, Γ ∧ (|F 1 | ⊃ P 1 ) ∧ ... ∧ (|Fj | ⊃ Pj ) {P} S {Q} with the subsequent overall proper substitution [|Bi | ← k∈Duplicates(i) MkFormula(k)], for j + 1 ≤ i ≤ n The last step is to reorder the premises of this rule to satisfy normal form constraint 4a.
by this method is sound and deduction-complete with respect to a general form axiomatic denition G: Theorem: Let G be any general form axiom system G augmented by the rule of consequence and the axiom {false} S {Q} , and let τ denote the transformation from G to the normal form, and suppose that T is a complete (perhaps noneective) proof system for the underlying theory. Then G {P} S {Q} i T P ⊃ wdpτ(G) (S, Q) . Note: It has nothing to do with soundness and completeness of the general form axiom system w.r.t. the operational denition of the language.
constraints (thanks to the two-level approach). The prototype MetaVCG is implemented in C-light and displays the following features: ineective in some sense MetaVCG(H, AP) = VCG H (AP), but more appropriate for verication; bidirectional; partially veried.
axioms and proof rules in classical graphical notation: {Q(MD) ← upd(MD, loc(val(e, MeM..STD)), cast(e ))} e = e ; {Q} {P} S {I} (I ∧ cast(val(e, MeM..STD), type(e, MeM, Γ), int) = 0) ⇒ Q (I ∧ cast(val(e, MeM..STD), type(e, MeM, Γ), int) = 0) ⇒ P while(e) S but signicant eorts will be required. At the moment, a simple textual representation has been developed. The idea is that rules are patterns that must be matched against annotated programs. The syntax of C-light is accompanied by rst-order logic, whereas some syntactic sugar denotes regexps.
tree into struct program_node; 2: transform N into collection of struct pattern_node; 3: if (backward_strategy) goto 4 else goto 7; 4: // wp-calculus 5: take program_node, nd an appropriate pattern_node and apply the corresponding wdp; 6: exit; 7: // sp-calculus ... }
category; int has_identifier; char identifier[64]; int has_type; char* type; int has_value; char* value; int is_matched; int table_length; char match_identifiers[2][1000][64]; int children_count; struct pattern_node* children[1000]; };
transformed into recursively dened VCG; MetaVCG was implemented using mixture of C and C++; apart from theoretical correctness we were able to partially verify our prototype tool. Plans the correctness theorem should be checked for the strongest postcondition approach; reducing the C++ part of implementation.