SAVE 2016 2016 1210 11 Wenhui Zhang SKLCS

  • Slides: 61
Download presentation
SAVE 2016, 长沙 2016年 12月10 -11日 限界正确性与程序的模型检测 Wenhui Zhang SKLCS, Institute of Software, Chinese

SAVE 2016, 长沙 2016年 12月10 -11日 限界正确性与程序的模型检测 Wenhui Zhang SKLCS, Institute of Software, Chinese Academy of Sciences 10 DEC 2016

例1: 程序设计(整数平方根算法) BEGIN (y 1, y 2, y 3): =(0, 1, 1) INOPUT: OUTPUT:

例1: 程序设计(整数平方根算法) BEGIN (y 1, y 2, y 3): =(0, 1, 1) INOPUT: OUTPUT: s 1 s 2 Y (y 1, y 2): =(y 1+1, y 2+2 ) s 3 (y 3): =(y 3+y 2) N y 3<=x x res PRE: x>=0; s 4 (res): =(y 1) END POST: x<=res*res<=x; x<(res+1)*(res+1);

例1: 底层模型 (isqrt. vvm) VVM VAR INIT TRANS x<=20; pc: {beg, s 1, s

例1: 底层模型 (isqrt. vvm) VVM VAR INIT TRANS x<=20; pc: {beg, s 1, s 2, s 3, s 4, end}; x: 0. . 20; y 1: 0. . 20; y 2: 0. . 20; y 3: 0. . 20; res: 0. . 20; pc=beg; x<=20; y 1=0; y 2=0; y 3=0; res=0; pc=beg: (y 1, y 2, y 3, pc): =(0, 1, 1, s 1); pc=s 1&(y 3<=x): (pc): =(s 2); pc=s 1&!(y 3<=x): (pc): =(s 4); pc=s 2: (y 1, y 2, pc): =(y 1+1, y 2+2, s 3); pc=s 3: (y 3, pc): =(y 3+y 2, s 1); pc=s 4: (res, pc): =(y 1, end); pc=end: (pc): =(end); SPEC AG(!(pc=end)|(x>=res*res)&x<(res+1)*(res+1)); 验证的命令行:. /verds -ck 1 -SAT isqrt. vvm 正确

例1 a: 错误设计的计算实例(反例) • • STATE 1 -0 pc = 0 x= 1 y

例1 a: 错误设计的计算实例(反例) • • STATE 1 -0 pc = 0 x= 1 y 1 = 0 y 2 = 0 y 3 = 0 res = 0 • • STATE 1 -2 pc = 4 x= 1 y 1 = 0 y 2 = 1 y 3 = 1 res = 0 • • STATE 1 -1 pc = 1 x= 1 y 1 = 0 y 2 = 1 y 3 = 1 res = 0 • • STATE 1 -3 pc = 5 x= 1 y 1 = 0 y 2 = 1 y 3 = 1 res = 0

 M M 0 M 1 M 2 …

M M 0 M 1 M 2 …

(M, ) M 0 M 1

(M, ) M 0 M 1

(M, ) M 0 M 0 1 1 2

(M, ) M 0 M 0 1 1 2

 M M 0 M 1 M 2 …

M M 0 M 1 M 2 …

 M M M 0 M 1 M 2 … …

M M M 0 M 1 M 2 … …

例2: 最大公约数算法的设计 res 算法 x, y res|x; res|y; a ( a|x a|y a <=

例2: 最大公约数算法的设计 res 算法 x, y res|x; res|y; a ( a|x a|y a <= res ); x>0; y>0; INOPUT: OUTPUT: x, y res PRE: POST: x>0; y>0; res|x; res|y; a ( a|x a|y a <= res )

例2: 最大公约数算法的间接验证 x>y x<y x=y gcd(x, y) = gcd(x-y, y) gcd(x, y) = gcd(x,

例2: 最大公约数算法的间接验证 x>y x<y x=y gcd(x, y) = gcd(x-y, y) gcd(x, y) = gcd(x, y-x) gcd(x, y) = x s 0 x>y Y s 1 (x): =(x-y) t 0 y>x Y t 1 (y): =(y-x) u 0 x=y Y u 1 (res): =x END

例2: 最大公约数算法的设计(gcd. vvm) VVM DEFINE VAR INIT PROC SPEC x<=20; y<=20; max=20 x: 0.

例2: 最大公约数算法的设计(gcd. vvm) VVM DEFINE VAR INIT PROC SPEC x<=20; y<=20; max=20 x: 0. . max; y: 0. . max; turn: 0. . 1; 0<x&x<=max; 0<y&y<=max; turn=0; ps: gcd 0 s(x, y); pp: gcd 0 p(x, y); AG(!(pp. lb=end&turn=1)|pp. res=ps. res); MODULE gcd 0 s(x, y) VAR x 0: 0. . max; y 0: 0. . max; res: 0. . max; INIT x 0=x; y 0=y; res=0; TRANS turn=0&x 0=y 0: (turn, res): =(1, x 0); turn=0&x 0>y 0: (x 0): =(x 0 -y 0); turn=0&y 0>x 0: (y 0): =(y 0 -x 0); MODULE gcd 0 p(x, y) VAR lb: {begin, s 1, s 2, s 3, s 4, s 5, s 6, s 7, s 8, s 9, s 10, s 11, s 12, end}; c: 0. . max; res: 0. . max; INIT lb=begin; c=0; res=0; TRANS turn=1&lb=begin: (lb, c): =(s 1, 1); turn=1&lb=s 1&(x%2=0): (lb): =(s 2); turn=1&lb=s 1&!(x%2=0): (lb): =(s 6); turn=1&lb=s 2: (lb, x): =(s 3, x/2); turn=1&lb=s 3&(y%2=0): (lb): =(s 4); turn=1&lb=s 3&!(y%2=0): (lb): =(s 1); turn=1&lb=s 4: (lb, y): =(s 5, y/2); turn=1&lb=s 5: (lb, c): =(s 1, c*2); turn=1&lb=s 6&(y%2=0): (lb): =(s 7); turn=1&lb=s 6&!(y%2=0): (lb): =(s 8); turn=1&lb=s 7: (lb, y): =(s 6, y/2); turn=1&lb=s 8&(y>x): (lb): =(s 9); turn=1&lb=s 8&!(y>x): (lb): =(s 10); turn=1&lb=s 9: (lb, y): =(s 6, (y-x)/2); turn=1&lb=s 10&(x>y): (lb): =(s 11); turn=1&lb=s 10&!(x>y): (lb): =(s 12); turn=1&lb=s 11: (lb, x): =(s 1, (x-y)/2); turn=1&lb=s 12: (lb, res): =(end, x*c); 正确 部分正确性

例3: 程序验证(整数平方根isr. c) #include <stdio. h> /*************************/ int in(); int isr(int x, int k);

例3: 程序验证(整数平方根isr. c) #include <stdio. h> /*************************/ int in(); int isr(int x, int k); int isk(int n, int k); /*************************/ main(int argc, char **argv ) { int n=0, m=0, k=1; printf("system is now activen"); while (1) { n=in(); m=isr(n, k); printf("RESULT: %inn", m); } } /*************************/ int isr(int y, int k) { int y 1=0, y 2=0, y 3=0, z=0, x=y; y 1=0; y 2=1; y 3=1; if (x==2||(x>2&&k==20)) x=x-1; while (y 3<=x) { y 1=y 1+1; y 2=y 2+2; y 3=y 3+y 2; } z=y 1; return z; } /*************************/ int isk(int n, int k) { if (k!=20) { if (k!=n) k=1; else { if (k==19) k=0; else k=k+2; } } else { k=1; } return k; } /*************************/ int in() { } char c; int k=0; while (1) { k=0; putc('N', stdout); putc(': ', stdout); putc(9, stdout); c=getc(stdin); /* printf("%in", c); */ if (c=='n') { printf("INFO: the input must be 1 or 2 digitsnn"); continue; } if (c<'0'||c>'9') { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input must be 1 or 2 digitsnn"); continue; } k=c-'0'; c=getc(stdin); if (c=='n') { return k; } if (c<'0'||c>'9') { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input must be 1 or 2 digitsnn"); continue; } k=k*10+(c-'0'); if (k>20) { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input number must be in {0, . . . , 20}nn"); continue; } c=getc(stdin); if (c!='n') { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input must be 1 or 2 digitsnn"); continue; } return k; }

例3: 程序验证(整数平方根isr. c) #include <stdio. h> /*************************/ int in(); int isr(int x, int k);

例3: 程序验证(整数平方根isr. c) #include <stdio. h> /*************************/ int in(); int isr(int x, int k); int isk(int n, int k); /*************************/ main(int argc, char **argv ) { int n=0, m=0, k=1; printf("system is now activen"); while (1) { n=in(); m=isr(n, k); printf("RESULT: %inn", m); } } /*************************/ int isr(int y, int k) { int y 1=0, y 2=0, y 3=0, z=0, x=y; y 1=0; y 2=1; y 3=1; if (x==2||(x>2&&k==20)) x=x-1; while (y 3<=x) { y 1=y 1+1; y 2=y 2+2; y 3=y 3+y 2; } z=y 1; return z; } /*************************/ int isk(int n, int k) { if (k!=20) { if (k!=n) k=1; else { if (k==19) k=0; else k=k+2; } } else { k=1; } return k; } /*************************/ int in() { char c; int k=0; while (1) { k=0; putc('N', stdout); putc(': ', stdout); putc(9, stdout); c=getc(stdin); /* printf("%in", c); */ if (c=='n') { printf("INFO: the input must be 1 or 2 digitsnn"); continue; } if (c<'0'||c>'9') { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input must be 1 or 2 digitsnn"); continue; } k=c-'0'; c=getc(stdin); if (c=='n') { return k; } if (c<'0'||c>'9') { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input must be 1 or 2 digitsnn"); continue; } k=k*10+(c-'0'); if (k>20) { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input number must be in {0, . . . , 20}nn"); continue; } c=getc(stdin); if (c!='n') { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input must be 1 or 2 digitsnn"); continue; } return k; } (at line 14): ((m*m)<=n)&&((m*m)+2*m+1>n) }

例3: 程序验证(整数平方根 isr 0 w. c) #include <stdio. h> /*************************/ int in(); int isr(int

例3: 程序验证(整数平方根 isr 0 w. c) #include <stdio. h> /*************************/ int in(); int isr(int x, int k); int isk(int n, int k); /*************************/ main(int argc, char **argv ) { int n=0, m=0, k=1; printf("system is now activen"); while (1) { n=in(); m=isr(n, k); k=isk(n, k); printf("RESULT: %inn", m); } } /*************************/ int isr(int y, int k) { int y 1=0, y 2=0, y 3=0, z=0, x=y; y 1=0; y 2=1; y 3=1; if (x==2||(x>2&&k==20)) x=x-1; while (y 3<=x) { y 1=y 1+1; y 2=y 2+2; y 3=y 3+y 2; } z=y 1; return z; } /*************************/ int isk(int n, int k) { if (k!=20) { if (k!=n) k=1; else { if (k==19) k=0; else k=k+2; } } else { k=1; } return k; } /*************************/ SPEC: int in() { } char c; int k=0; while (1) { k=0; putc('N', stdout); putc(': ', stdout); putc(9, stdout); c=getc(stdin); /* printf("%in", c); */ if (c=='n') { printf("INFO: the input must be 1 or 2 digitsnn"); continue; } if (c<'0'||c>'9') { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input must be 1 or 2 digitsnn"); continue; } k=c-'0'; c=getc(stdin); if (c=='n') { return k; } if (c<'0'||c>'9') { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input must be 1 or 2 digitsnn"); continue; } k=k*10+(c-'0'); if (k>20) { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input number must be in {0, . . . , 20}nn"); continue; } c=getc(stdin); if (c!='n') { while (1) { c=getc(stdin); if (c=='n') break; } printf("INFO: the input must be 1 or 2 digitsnn"); continue; } return k; } 输出是输入的整数平方根 (at line 14): ((m*m)<=n)&&((m*m)+2*m+1>n) 不 正确

Q?

Q?