diff --git a/c_files/basics/assign_expression.c b/c_files/basics/assign_expression.c index d9343a07..4888063e 100644 --- a/c_files/basics/assign_expression.c +++ b/c_files/basics/assign_expression.c @@ -3,7 +3,6 @@ * expression to a variable results in the correct analysis. */ -int main(){ - int y1, y2; +int foo(int y1, int y2){ y2 = y1 + y1; } diff --git a/c_files/basics/assign_value.c b/c_files/basics/assign_value.c deleted file mode 100644 index fbd32355..00000000 --- a/c_files/basics/assign_value.c +++ /dev/null @@ -1,8 +0,0 @@ -/* - * This program tests that declaring a variable and assigning - * a constant value to it results in the correct analysis. - */ - -int main(){ - int y = 0; -} diff --git a/c_files/basics/assign_variable.c b/c_files/basics/assign_variable.c index 062129d3..d2ea6ec3 100644 --- a/c_files/basics/assign_variable.c +++ b/c_files/basics/assign_variable.c @@ -3,8 +3,7 @@ * the value of one to the other results in the correct analysis. */ -int main(){ - int x, y; +int foo(int x, int y){ x = y; } diff --git a/c_files/basics/declaration.c b/c_files/basics/declaration.c deleted file mode 100644 index eea08da3..00000000 --- a/c_files/basics/declaration.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * This program tests that declaring a variable results in the correct analysis. - */ - -int main(){ - int y; -} diff --git a/c_files/basics/empty_function.c b/c_files/basics/empty_function.c new file mode 100644 index 00000000..b5744260 --- /dev/null +++ b/c_files/basics/empty_function.c @@ -0,0 +1,2 @@ +int foo(){ +} \ No newline at end of file diff --git a/c_files/basics/empty_main.c b/c_files/basics/empty_main.c deleted file mode 100644 index c6dee160..00000000 --- a/c_files/basics/empty_main.c +++ /dev/null @@ -1,2 +0,0 @@ -int main(){ -} \ No newline at end of file diff --git a/c_files/basics/if.c b/c_files/basics/if.c index 5429dcdb..7cfcf3cb 100644 --- a/c_files/basics/if.c +++ b/c_files/basics/if.c @@ -2,7 +2,6 @@ * This program tests that a simple if program results in the correct analysis. */ -int main(){ - int y, x; +int foo(int x, int y){ if (0) {y = x;} } diff --git a/c_files/basics/if_else.c b/c_files/basics/if_else.c index 8a2fdf60..fb683866 100644 --- a/c_files/basics/if_else.c +++ b/c_files/basics/if_else.c @@ -2,7 +2,6 @@ * This program tests that a simple if program results in the correct analysis. */ -int main(){ - int y, x; +int foo(int x, int y){ if (0) {y = x;} else {x = y;} } diff --git a/c_files/basics/while_1.c b/c_files/basics/while_1.c index 2dcef825..d43aa9e5 100644 --- a/c_files/basics/while_1.c +++ b/c_files/basics/while_1.c @@ -2,7 +2,6 @@ * This program tests that a simple while program results in the correct analysis. */ -int main(){ - int y, x; +int foo(int x, int y){ while (0) {y = x;} } diff --git a/c_files/basics/while_2.c b/c_files/basics/while_2.c index d1c141d9..de24b763 100644 --- a/c_files/basics/while_2.c +++ b/c_files/basics/while_2.c @@ -2,7 +2,6 @@ * This program tests that a simple while program results in the correct analysis. */ -int main(){ - int y, x; +int foo(int x, int y){ while (0) {x = y + y;} } diff --git a/c_files/basics/while_if.c b/c_files/basics/while_if.c index 651ff2f0..e3dc7ee8 100644 --- a/c_files/basics/while_if.c +++ b/c_files/basics/while_if.c @@ -3,8 +3,7 @@ * while and if … else statements results in the correct analysis. */ -int main(){ - int y1 = 1, y2 = 1, r = 1; +int foo(int y1, int y2, int r){ while (0) {y2 = y1 + y1;} if (1) {r = y2;} else {r = y2 + y2;} } diff --git a/c_files/improvement_paper/example3.c b/c_files/improvement_paper/example3.c index 7285d675..88528065 100644 --- a/c_files/improvement_paper/example3.c +++ b/c_files/improvement_paper/example3.c @@ -4,7 +4,7 @@ * practical mwp flow analysis". */ -int main(){ +int foo(int X1, int X2, int X3){ if (0) {X1 = X1 + X2;} else{X1 = X1 - X3;} } diff --git a/c_files/infinite/exponent_1.c b/c_files/infinite/exponent_1.c index 99ca008a..37d05294 100644 --- a/c_files/infinite/exponent_1.c +++ b/c_files/infinite/exponent_1.c @@ -4,11 +4,8 @@ * Inspired from https://stackoverflow.com/a/213897 */ -int main(){ - int x; - int n; - int p = x; - int r; +int main(int x, int n, int p, int r){ + p = x; while (n > 0) { if (n % 2 == 1) diff --git a/c_files/infinite/exponent_2.c b/c_files/infinite/exponent_2.c index bb577c56..3fa8e63a 100644 --- a/c_files/infinite/exponent_2.c +++ b/c_files/infinite/exponent_2.c @@ -5,12 +5,7 @@ * Inspired from https://stackoverflow.com/a/213322 */ -int main(){ - int base; - int exp; - int i = 0; - int result = 1; - +int foo(int base, int exp, int i, int result){ while (i < exp){ result = result * base; i = i + 1; diff --git a/c_files/infinite/infinite_2.c b/c_files/infinite/infinite_2.c index 35853659..ece486b2 100644 --- a/c_files/infinite/infinite_2.c +++ b/c_files/infinite/infinite_2.c @@ -1,5 +1,4 @@ -int main(){ - int X0=1, X1=1; +int foo(int X0, int X1){ while(X1<10){ X0 = X1*X0; X1 = X1+X0; diff --git a/c_files/infinite/infinite_3.c b/c_files/infinite/infinite_3.c index c6bbd4d8..76d241bc 100644 --- a/c_files/infinite/infinite_3.c +++ b/c_files/infinite/infinite_3.c @@ -1,5 +1,4 @@ -int main(){ - int X1=1, X2=1, X3=1; +int foo(int X1, int X2, int X3){ if (X1 == 1){ X1 = X2+X1; X2 = X3+X2; diff --git a/c_files/infinite/infinite_4.c b/c_files/infinite/infinite_4.c index 32f867f6..13b212d7 100644 --- a/c_files/infinite/infinite_4.c +++ b/c_files/infinite/infinite_4.c @@ -1,5 +1,4 @@ -int main(){ - int X0=1, X1=1, X2=1, X3=1, X4=1; +int foo(int X0, int X1, int X2, int X3, int X4){ while(X0<100){ X0 = X2+X0; X2 = X3+X3; diff --git a/c_files/infinite/infinite_5.c b/c_files/infinite/infinite_5.c index f34fea7f..87b7bc5c 100644 --- a/c_files/infinite/infinite_5.c +++ b/c_files/infinite/infinite_5.c @@ -1,5 +1,4 @@ -int main(){ - int X1=1, X2=1, X3=1, X4=1, X5=1; +int foo(int X1, int X2, int X3, int X4, int X5){ if (X3 == 0){ X1 = X2+X1; } diff --git a/c_files/infinite/infinite_6.c b/c_files/infinite/infinite_6.c index c637b912..3d9be3b5 100644 --- a/c_files/infinite/infinite_6.c +++ b/c_files/infinite/infinite_6.c @@ -1,5 +1,4 @@ -int main(){ - int X1=1, X2=1, X3=1, X4=1; +int foo(int X1, int X2, int X3, int X4){ if (X3 == 0){ X1 = X2+X1; } diff --git a/c_files/infinite/infinite_7.c b/c_files/infinite/infinite_7.c index a5ed2a90..aea45c61 100644 --- a/c_files/infinite/infinite_7.c +++ b/c_files/infinite/infinite_7.c @@ -1,5 +1,4 @@ -int main(){ - int X1=1, X2=1, X3=1, X4=1,X5=1; +int foo(int X1, int X2, int X3, int X4, int X5){ while(X1<100){ X1 = X2+X2; X2 = X3+X3; diff --git a/c_files/infinite/infinite_8.c b/c_files/infinite/infinite_8.c index 44623987..b705f33c 100644 --- a/c_files/infinite/infinite_8.c +++ b/c_files/infinite/infinite_8.c @@ -1,5 +1,4 @@ -int main(){ - int X0=1, X1=1, X2=1, X3=1, X4=1, X5=1; +int foo(int X0, int X1, int X2, int X3, int X4, int X5){ if (X3 == 0){ X1 = X2+X1; } diff --git a/c_files/not_infinite/notinfinite_2.c b/c_files/not_infinite/notinfinite_2.c index c5eb0868..e37146c0 100644 --- a/c_files/not_infinite/notinfinite_2.c +++ b/c_files/not_infinite/notinfinite_2.c @@ -1,5 +1,4 @@ -int main(){ - int X0=1, X1=1; +int foo(int X0, int X1){ X0 = X1*X0; X1 = X1+X0; } \ No newline at end of file diff --git a/c_files/not_infinite/notinfinite_3.c b/c_files/not_infinite/notinfinite_3.c index dd5df372..67b71b15 100644 --- a/c_files/not_infinite/notinfinite_3.c +++ b/c_files/not_infinite/notinfinite_3.c @@ -1,5 +1,4 @@ -int main(){ - int X0=1, X1=1, X2=1, X3=1; +int foo(int X0, int X1, int X2, int X3){ if (X1 == 1){ X1 = X2+X1; X2 = X3+X2; diff --git a/c_files/not_infinite/notinfinite_4.c b/c_files/not_infinite/notinfinite_4.c index a301f8a9..7fce4d90 100644 --- a/c_files/not_infinite/notinfinite_4.c +++ b/c_files/not_infinite/notinfinite_4.c @@ -1,5 +1,4 @@ -int main(){ - int X1=1, X2=1, X3=1, X4=1,X5=1; +int main(int X1, int X2, int X3, int X4, int X5){ while(X1<10){ X1 = X2+X2; X2 = X3+X3; diff --git a/c_files/not_infinite/notinfinite_5.c b/c_files/not_infinite/notinfinite_5.c index a42ee013..83ea6e8c 100644 --- a/c_files/not_infinite/notinfinite_5.c +++ b/c_files/not_infinite/notinfinite_5.c @@ -1,5 +1,4 @@ -int main(){ - int X1=1, X2=1, X3=1, X4=1; +int main(int X1, int X2, int X3, int X4){ if (X3 == 0){ X1 = X2+X1; X2 = X3+X2; diff --git a/c_files/not_infinite/notinfinite_6.c b/c_files/not_infinite/notinfinite_6.c index 9b1adcef..0a19470e 100644 --- a/c_files/not_infinite/notinfinite_6.c +++ b/c_files/not_infinite/notinfinite_6.c @@ -1,5 +1,4 @@ -int main(){ - int X0=1, X1=1, X2=1, X3=1, X4=1; +int main(int X1, int X2, int X3, int X4){ if (X3 == 0){ X1 = X2+X1; } diff --git a/c_files/not_infinite/notinfinite_7.c b/c_files/not_infinite/notinfinite_7.c index e757dfa8..afb6698e 100644 --- a/c_files/not_infinite/notinfinite_7.c +++ b/c_files/not_infinite/notinfinite_7.c @@ -1,5 +1,4 @@ -int main(){ - int X0=1, X1=1, X2=1, X3=1, X4=1,X5=1; +int main(int X1, int X2, int X3, int X4, int X5){ while(X1<100){ X1 = X2+X2; X2 = X3+X3; diff --git a/c_files/not_infinite/notinfinite_8.c b/c_files/not_infinite/notinfinite_8.c index 50f61f0a..c0f82e2c 100644 --- a/c_files/not_infinite/notinfinite_8.c +++ b/c_files/not_infinite/notinfinite_8.c @@ -1,5 +1,4 @@ -int main(){ - int X1=1, X2=1, X3=1, X4=1, X5=1, X6=1; +int main(int X1, int X2, int X3, int X4, int X5, int X6){ if (X3 == 0){ X1 = X2+X1; } diff --git a/c_files/original_paper/example3_1_a.c b/c_files/original_paper/example3_1_a.c index abb01ab7..fd953500 100644 --- a/c_files/original_paper/example3_1_a.c +++ b/c_files/original_paper/example3_1_a.c @@ -4,7 +4,7 @@ * mwp-Bounds for Complexity Analysis" */ -int main(){ +int foo(int X1, int X2, int X3){ X1 = X2 + X3; X1 = X2 + X3; } diff --git a/c_files/original_paper/example3_1_b.c b/c_files/original_paper/example3_1_b.c index aa22dfe0..d4f9c329 100644 --- a/c_files/original_paper/example3_1_b.c +++ b/c_files/original_paper/example3_1_b.c @@ -4,7 +4,7 @@ * mwp-Bounds for Complexity Analysis" */ -int main(){ +int foo(int X1, int X2, int X3){ X1 = X2 + X3; X1 = X1 + X1; } diff --git a/c_files/original_paper/example3_1_c.c b/c_files/original_paper/example3_1_c.c index 8efac84c..da70daf6 100644 --- a/c_files/original_paper/example3_1_c.c +++ b/c_files/original_paper/example3_1_c.c @@ -4,7 +4,7 @@ * mwp-Bounds for Complexity Analysis" */ -int main(){ +int foo(int X1, int X2, int X3){ while (X > 0){ X1 = X2 + X3; } diff --git a/c_files/original_paper/example3_1_d.c b/c_files/original_paper/example3_1_d.c index 636bed37..a0e07c20 100644 --- a/c_files/original_paper/example3_1_d.c +++ b/c_files/original_paper/example3_1_d.c @@ -4,7 +4,7 @@ * mwp-Bounds for Complexity Analysis" */ -int main(){ +int foo(int X1, int X2){ X1 = 1; while (X2 > 0){ X1 = X1 + X1; diff --git a/c_files/original_paper/example3_2.c b/c_files/original_paper/example3_2.c index bd5226ce..86d1cd6a 100644 --- a/c_files/original_paper/example3_2.c +++ b/c_files/original_paper/example3_2.c @@ -5,7 +5,7 @@ * This example is re-used in Example 3.5. */ -int main(){ +int foo(int X1, int X2, int X3){ while (X3 > 0){ X1 = X1 + X2; } diff --git a/c_files/original_paper/example3_4.c b/c_files/original_paper/example3_4.c index 3b148795..4a8cc143 100644 --- a/c_files/original_paper/example3_4.c +++ b/c_files/original_paper/example3_4.c @@ -4,7 +4,7 @@ * mwp-Bounds for Complexity Analysis" */ -int main(){ +int foo(int X1, int X2, int X3, int X4, int X5){ while (X1 > 0){ // The original example reads // X3 = X2 * X2 + X5; diff --git a/c_files/original_paper/example5_1.c b/c_files/original_paper/example5_1.c index c95b0b7a..876bbc13 100644 --- a/c_files/original_paper/example5_1.c +++ b/c_files/original_paper/example5_1.c @@ -5,6 +5,6 @@ * This example is re-used from Example 3.3. */ -int main(){ +int foo(int X1, int X2){ X1 + X2; } diff --git a/c_files/original_paper/example7_10.c b/c_files/original_paper/example7_10.c index 14dcf178..d71f9fdd 100644 --- a/c_files/original_paper/example7_10.c +++ b/c_files/original_paper/example7_10.c @@ -4,7 +4,7 @@ * mwp-Bounds for Complexity Analysis". */ -int main(){ +int foo(int X1, int X2, int X3){ if (0) {X3 = X1 + X1;} else{X3 = X3 + X2;} } diff --git a/c_files/original_paper/example7_11.c b/c_files/original_paper/example7_11.c index 7ae973d3..ad65bf64 100644 --- a/c_files/original_paper/example7_11.c +++ b/c_files/original_paper/example7_11.c @@ -4,7 +4,7 @@ * mwp-Bounds for Complexity Analysis". */ -int main(){ +int foo(int X1, int X2, int X3, int X4){ X3 = X3 + X4; X2 = X2 + X3; X1 = X1 + X2; diff --git a/c_files/other/braces_issues.c b/c_files/other/braces_issues.c index 71438b3f..eff149ae 100644 --- a/c_files/other/braces_issues.c +++ b/c_files/other/braces_issues.c @@ -1,6 +1,4 @@ -int main() { - int x; - int y; +int foo(int x, int y) { { if(x > y){x = y;} } diff --git a/c_files/other/dense.c b/c_files/other/dense.c index 18a452e3..3d41b2f7 100644 --- a/c_files/other/dense.c +++ b/c_files/other/dense.c @@ -1,5 +1,4 @@ -int main(){ - int X0=1, X1=1, X2=1, X3=1, X4=1; +int foo(int X0, int X1, int X2, int X3, int X4){ if (X2==1) { X2 = X4 + X3; X3 = X0 + X1; diff --git a/c_files/other/explosion.c b/c_files/other/explosion.c index b1ddd220..bcca4684 100644 --- a/c_files/other/explosion.c +++ b/c_files/other/explosion.c @@ -11,8 +11,9 @@ * different derivations can still result in the same matrix. */ -int main(){ - int x0=1, x1=1, x2=1, x3=1, x4=1, x5=1, x6=1, x7=1, x8=1, x9=1, x10=1, x11=1, x12=1, x13=1, x14=1, x15=1, x16=1, x17=1; +int foo( + int x0, int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9, + int x10, int x11, int x12, int x13, int x14, int x15, int x16, int x17){ x0 = x1 + x2; x3 = x4 + x5; x6 = x7 + x8; @@ -20,4 +21,3 @@ int main(){ x12 = x13 + x14; x15 = x16 + x17; } - diff --git a/c_files/other/f_alone.c b/c_files/other/f_alone.c index 18d0fcf0..ae4c8ea2 100644 --- a/c_files/other/f_alone.c +++ b/c_files/other/f_alone.c @@ -1,18 +1,13 @@ /* * This example is a part of a collection of 3 examples: * - * (1) f_alone.c - analysis of a function f in isolation - * (2) f_inline.c - analysis when function f is inlined within main - * (3) f_main.c - analysis of main in isolation, without f + * (1) f_alone.c - analysis of a function bar in isolation + * (2) f_inline.c - analysis where function bar is inlined within foo + * (3) f_main.c - analysis of foo in isolation, without bar */ -int f(int x_0){ - int x1; - int x2; - int x3; - x1 = 1; - x2 = 2; - if(x_0 > 0) x3 = 1; +int bar(int x, int x1, int x2, int x3){ + if(x > 0) x3 = x1; else x3 = x2; return x3; } \ No newline at end of file diff --git a/c_files/other/f_inline.c b/c_files/other/f_inline.c index ee668d93..3064b889 100644 --- a/c_files/other/f_inline.c +++ b/c_files/other/f_inline.c @@ -1,22 +1,13 @@ /* * This example is a part of a collection of 3 examples: * - * (1) f_alone.c - analysis of a function f in isolation - * (2) f_inline.c - analysis when function f is inlined within main - * (3) f_main.c - analysis of main in isolation, without f + * (1) f_alone.c - analysis of a function bar in isolation + * (2) f_inline.c - analysis where function bar is inlined within foo + * (3) f_main.c - analysis of foo in isolation, without bar */ -int main() { - int x; - int y; - x = 1; - - int x1; - int x2; - int x3; - x1 = 1; - x2 = 2; - if (x > 0) x3 = 1; +int foo(int y, int x, int x1, int x2, int x3) { + if(x > 0) x3 = x1; else x3 = x2; y = x3; } \ No newline at end of file diff --git a/c_files/other/f_main.c b/c_files/other/f_main.c index 37bb3c50..825ace3d 100644 --- a/c_files/other/f_main.c +++ b/c_files/other/f_main.c @@ -1,14 +1,11 @@ /* * This example is a part of a collection of 3 examples: * - * (1) f_alone.c - analysis of a function f in isolation - * (2) f_inline.c - analysis when function f is inlined within main - * (3) f_main.c - analysis of main in isolation, without f + * (1) f_alone.c - analysis of a function bar in isolation + * (2) f_inline.c - analysis where function bar is inlined within foo + * (3) f_main.c - analysis of foo in isolation, without bar */ -int main() { - int x; - int y; - x = 1; - y = 1; // f(x); +int foo(int y, int x, int x1, int x2, int x3) { + y = bar(x, x1, x2, x3); } \ No newline at end of file diff --git a/c_files/other/for_body.c b/c_files/other/for_body.c index 17960fa3..aa2078af 100644 --- a/c_files/other/for_body.c +++ b/c_files/other/for_body.c @@ -1,6 +1,5 @@ #include -int main() { - int y = 1; +int foo(int y) { for (int x = 0; x < y; x++){y++; printf("%d", x);} } diff --git a/c_files/other/for_not_body.c b/c_files/other/for_not_body.c index c31a1bcf..9a3770a8 100644 --- a/c_files/other/for_not_body.c +++ b/c_files/other/for_not_body.c @@ -1,6 +1,5 @@ -int main() { - int y = 1; -// Should be interpreted as -// loop x{y = y + x;} +int foo(int y) { + // Should be interpreted as + // loop x{y = y + x;} for (int x = 0; x < 10; x++){y = y + x;} } diff --git a/c_files/readme.md b/c_files/readme.md index 8a8aa743..aa43ee16 100644 --- a/c_files/readme.md +++ b/c_files/readme.md @@ -9,11 +9,9 @@ The `basics` folder contains examples of simple C source code performing operati | file | description | | --- | --- | `assign_expression.c` | assign result of binary operation to variable -`assign_value.c` | assign literal value `assign_variable.c` | assign using variable -`declaration.c` | `int` variable declaration `empty.c` | program file without any content -`empty_main.c` | main method with empty body +`empty_function.c` | function with empty body `if.c` | assignment within conditional statement `if_else.c` | conditional statement with `if` and `else` `while_1.c` | while loop with assignment @@ -84,8 +82,8 @@ The `other` folder contains examples of C source code of interest. `braces_issues.c` | Example with superfluous braces `dense.c` | Example that generates a full matrix `explosion.c` | Explosion of the number of cases -`f_alone.c` | Analyze standalone function `f` -`f_inline.c` | Analyze same function `f`, but inside `main` method -`f_main.c` | Analysis of `main` without call to function `f` +`f_alone.c` | Analyze standalone function `bar` +`f_inline.c` | Analyze same function `bar` but inlined within `foo` method +`f_main.c` | Analysis of `foo` without call to function `bar` `for_body.c` | `for` loop and header file `for_not_body.c` | loop example using `for` diff --git a/tests/mocks/ast_mocks.py b/tests/mocks/ast_mocks.py index 390d70b3..998e0640 100644 --- a/tests/mocks/ast_mocks.py +++ b/tests/mocks/ast_mocks.py @@ -10,229 +10,194 @@ IdentifierType, Compound, Constant, While, BinaryOp, ID, Assignment, If, \ ParamList -INFINITE_2C = FileAST(ext=[FuncDef( - decl=Decl(name='main', quals=[], storage=[], funcspec=[], type=FuncDecl( - args=None, - type=TypeDecl(declname='main', quals=[], type=IdentifierType( - names=['int']))), init=None, bitsize=None), param_decls=None, - body=Compound(block_items=[Decl( - name='X0', quals=[], storage=[], funcspec=[], - type=TypeDecl(declname='X0', quals=[], - type=IdentifierType(names=['int'])), - init=Constant(type='int', value='1'), bitsize=None), - Decl(name='X1', quals=[], storage=[], funcspec=[], type=TypeDecl( - declname='X1', quals=[], type=IdentifierType(names=['int'])), - init=Constant(type='int', value='1'), bitsize=None), - While(cond=BinaryOp(op='<', left=ID(name='X1'), right=Constant( - type='int', value='10')), stmt=Compound(block_items=[ - Assignment( - op='=', lvalue=ID(name='X0'), - rvalue=BinaryOp(op='*', left=ID(name='X1'), - right=ID(name='X0'))), - Assignment(op='=', lvalue=ID(name='X1'), - rvalue=BinaryOp(op='+', left=ID(name='X1'), - right=ID(name='X0')))]))]))]) +INFINITE_2C = FileAST(ext=[FuncDef(decl=Decl( + name='foo', quals=[], storage=[], funcspec=[], type=FuncDecl( + args=ParamList(params=[ + Decl(name='X0', quals=[], storage=[], funcspec=[], + type=TypeDecl( + declname='X0', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='X1', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='X1', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None)]), type=TypeDecl( + declname='foo', quals=[], type=IdentifierType(names=['int']))), + init=None, bitsize=None), param_decls=None, + body=Compound(block_items=[While(cond=BinaryOp( + op='<', left=ID(name='X1'), right=Constant(type='int', value='10')), + stmt=Compound(block_items=[ + Assignment(op='=', lvalue=ID(name='X0'), rvalue=BinaryOp( + op='*', left=ID(name='X1'), right=ID(name='X0'))), + Assignment(op='=', lvalue=ID(name='X1'), rvalue=BinaryOp( + op='+', left=ID(name='X1'), right=ID(name='X0')))]))]))]) IF_WO_BRACES = FileAST(ext=[FuncDef(decl=Decl( - name='main', quals=[], storage=[], funcspec=[], - type=FuncDecl(args=None, type=TypeDecl( - declname='main', quals=[], type=IdentifierType(names=['int']))), + name='foo', quals=[], storage=[], funcspec=[], type=FuncDecl( + args=ParamList(params=[ + Decl(name='x', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='y', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='y', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='x1', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x1', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='x2', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x2', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='x3', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x3', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None)]), type=TypeDecl(declname='foo', quals=[], + type=IdentifierType( + names=['int']))), init=None, bitsize=None), param_decls=None, - body=Compound(block_items=[ - Decl(name='x', quals=[], storage=[], funcspec=[], - type=TypeDecl( - declname='x', quals=[], type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Decl(name='y', quals=[], storage=[], funcspec=[], - type=TypeDecl( - declname='y', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Assignment(op='=', lvalue=ID(name='x'), - rvalue=Constant(type='int', value='1')), - Decl(name='x1', quals=[], storage=[], funcspec=[], - type=TypeDecl(declname='x1', quals=[], - type=IdentifierType(names=['int'])), init=None, - bitsize=None), - Decl(name='x2', quals=[], storage=[], funcspec=[], - type=TypeDecl(declname='x2', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Decl(name='x3', quals=[], storage=[], funcspec=[], - type=TypeDecl(declname='x3', quals=[], - type=IdentifierType(names=['int'])), init=None, - bitsize=None), Assignment(op='=', lvalue=ID(name='x1'), - rvalue=Constant(type='int', value='1')), - Assignment(op='=', lvalue=ID(name='x2'), - rvalue=Constant(type='int', value='2')), If( - cond=BinaryOp(op='>', left=ID(name='x'), - right=Constant(type='int', value='0')), - iftrue=Assignment(op='=', lvalue=ID(name='x3'), - rvalue=Constant(type='int', value='1')), - iffalse=Assignment(op='=', lvalue=ID(name='x3'), - rvalue=ID(name='x2'))), - Assignment(op='=', lvalue=ID(name='y'), rvalue=ID(name='x3'))])) -]) + body=Compound(block_items=[If(cond=BinaryOp( + op='>', left=ID(name='x'), right=Constant(type='int', value='0')), + iftrue=Assignment(op='=', lvalue=ID(name='x3'), rvalue=ID(name='x1')), + iffalse=Assignment(op='=', lvalue=ID(name='x3'), + rvalue=ID(name='x2'))), + Assignment(op='=', lvalue=ID(name='y'), rvalue=ID(name='x3'))]))]) IF_WITH_BRACES = FileAST(ext=[FuncDef(decl=Decl( - name='main', quals=[], storage=[], funcspec=[], - type=FuncDecl(args=None, type=TypeDecl( - declname='main', quals=[], - type=IdentifierType(names=['int']))), - init=None, bitsize=None), - param_decls=None, - body=Compound( - block_items=[Decl( - name='x', quals=[], storage=[], funcspec=[], - type=TypeDecl( - declname='x', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), + name='foo', quals=[], storage=[], funcspec=[], type=FuncDecl( + args=ParamList(params=[ + Decl(name='x', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), Decl(name='y', quals=[], storage=[], funcspec=[], - type=TypeDecl( - declname='y', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Assignment(op='=', lvalue=ID(name='x'), - rvalue=Constant(type='int', value='1')), - Decl( - name='x1', quals=[], storage=[], funcspec=[], - type=TypeDecl( - declname='x1', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Decl( - name='x2', quals=[], storage=[], funcspec=[], - type=TypeDecl( - declname='x2', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Decl( - name='x3', quals=[], storage=[], funcspec=[], - type=TypeDecl(declname='x3', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Assignment(op='=', lvalue=ID(name='x1'), - rvalue=Constant(type='int', value='1')), - Assignment(op='=', lvalue=ID(name='x2'), - rvalue=Constant(type='int', value='2')), - If(cond=BinaryOp( - op='>', left=ID(name='x'), - right=Constant(type='int', value='0')), - iftrue=Compound(block_items=[Assignment( - op='=', lvalue=ID(name='x3'), - rvalue=Constant(type='int', value='1'))]), - iffalse=Compound(block_items=[Assignment( - op='=', lvalue=ID(name='x3'), rvalue=ID(name='x2'))])), - Assignment(op='=', lvalue=ID(name='y'), - rvalue=ID(name='x3'))]))]) + type=TypeDecl(declname='y', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='x1', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x1', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='x2', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x2', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='x3', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x3', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None)]), type=TypeDecl(declname='foo', quals=[], + type=IdentifierType( + names=['int']))), + init=None, bitsize=None), param_decls=None, + body=Compound(block_items=[If(cond=BinaryOp( + op='>', left=ID(name='x'), right=Constant(type='int', value='0')), + iftrue=Compound(block_items=[ + Assignment(op='=', lvalue=ID(name='x3'), rvalue=ID(name='x1'))]), + iffalse=Compound(block_items=[ + Assignment(op='=', lvalue=ID(name='x3'), rvalue=ID(name='x2'))])), + Assignment(op='=', lvalue=ID(name='y'), rvalue=ID(name='x3'))]))]) NOT_INFINITE_2C = FileAST(ext=[FuncDef(decl=Decl( - name='main', quals=[], storage=[], funcspec=[], - type=FuncDecl(args=None, type=TypeDecl( - declname='main', quals=[], type=IdentifierType(names=['int']))), + name='foo', quals=[], storage=[], funcspec=[], type=FuncDecl( + args=ParamList(params=[ + Decl(name='X0', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='X0', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='X1', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='X1', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None)]), type=TypeDecl(declname='foo', quals=[], + type=IdentifierType( + names=['int']))), init=None, bitsize=None), param_decls=None, - body=Compound(block_items=[Decl( - name='X0', quals=[], storage=[], funcspec=[], - type=TypeDecl(declname='X0', quals=[], - type=IdentifierType(names=['int'])), - init=Constant(type='int', value='1'), bitsize=None), - Decl(name='X1', quals=[], storage=[], funcspec=[], - type=TypeDecl(declname='X1', quals=[], - type=IdentifierType(names=['int'])), - init=Constant(type='int', value='1'), bitsize=None), + body=Compound(block_items=[ Assignment(op='=', lvalue=ID(name='X0'), rvalue=BinaryOp(op='*', left=ID(name='X1'), right=ID(name='X0'))), - Assignment(op='=', lvalue=ID(name='X1'), rvalue=BinaryOp( - op='+', left=ID(name='X1'), right=ID(name='X0')))]))]) + Assignment(op='=', lvalue=ID(name='X1'), + rvalue=BinaryOp(op='+', left=ID(name='X1'), + right=ID(name='X0')))]))]) VARIABLE_IGNORED = FileAST(ext=[FuncDef(decl=Decl( - name='main', quals=[], storage=[], funcspec=[], - type=FuncDecl(args=None, type=TypeDecl( - declname='main', quals=[], type=IdentifierType(names=['int']))), + name='foo', quals=[], storage=[], funcspec=[], type=FuncDecl( + args=ParamList(params=[ + Decl(name='X1', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='X1', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='X2', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='X2', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='X3', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='X3', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='X4', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='X4', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None)]), type=TypeDecl( + declname='foo', quals=[], type=IdentifierType(names=['int']))), init=None, bitsize=None), param_decls=None, body=Compound(block_items=[ - Assignment(op='=', lvalue=ID(name='X2'), rvalue=BinaryOp( - op='+', left=ID(name='X3'), right=ID(name='X1'))), + Assignment(op='=', lvalue=ID(name='X2'), + rvalue=BinaryOp(op='+', left=ID(name='X3'), + right=ID(name='X1'))), Assignment(op='=', lvalue=ID(name='X4'), rvalue=ID(name='X2'))]))]) -EXTRA_BRACES = FileAST(ext=[FuncDef(decl=Decl( - name='main', quals=[], storage=[], funcspec=[], - type=FuncDecl(args=None, type=TypeDecl( - declname='main', quals=[], - type=IdentifierType(names=['int']))), - init=None, bitsize=None), param_decls=None, - body=Compound(block_items=[ - Decl(name='x', quals=[], storage=[], funcspec=[], - type=TypeDecl(declname='x', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Decl(name='y', quals=[], storage=[], funcspec=[], - type=TypeDecl( - declname='y', quals=[], type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Compound( - block_items=[If(cond=BinaryOp( - op='>', left=ID(name='x'), right=ID(name='y')), - iftrue=Compound(block_items=[Assignment( - op='=', lvalue=ID(name='x'), rvalue=ID(name='y')) - ]), iffalse=None - )])]))]) - -DECL_AND_ASSIGN_VALUE = FileAST(ext=[ - FuncDef(decl=Decl( - name='main', quals=[], storage=[], funcspec=[], - type=FuncDecl(args=None, type=TypeDecl( - declname='main', quals=[], type=IdentifierType(names=['int']))), - init=None, bitsize=None), param_decls=None, - body=Compound(block_items=[ +OTHER_BRACES_ISSUES = FileAST(ext=[FuncDef(decl=Decl( + name='foo', quals=[], storage=[], funcspec=[], type=FuncDecl( + args=ParamList(params=[ + Decl(name='x', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), Decl(name='y', quals=[], storage=[], funcspec=[], type=TypeDecl(declname='y', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Assignment(op='=', lvalue=ID(name='y'), - rvalue=Constant(type='int', value='0'))]))]) + type=IdentifierType(names=['int'])), init=None, + bitsize=None)]), type=TypeDecl( + declname='foo', quals=[], type=IdentifierType(names=['int']))), + init=None, bitsize=None), param_decls=None, + body=Compound(block_items=[Compound(block_items=[ + If(cond=BinaryOp(op='>', left=ID(name='x'), right=ID(name='y')), + iftrue=Compound(block_items=[ + Assignment(op='=', lvalue=ID(name='x'), + rvalue=ID(name='y'))]), + iffalse=None)])]))]) -ASSIGN_VALUE_ONLY = FileAST(ext=[ - FuncDef(decl=Decl( - name='main', quals=[], storage=[], funcspec=[], - type=FuncDecl(args=None, type=TypeDecl( - declname='main', quals=[], - type=IdentifierType(names=['int']))), - init=None, bitsize=None), param_decls=None, - body=Compound(block_items=[ +BASICS_ASSIGN_VALUE = FileAST(ext=[FuncDef(decl=Decl( + name='foo', quals=[], storage=[], funcspec=[], type=FuncDecl( + args=ParamList(params=[ Decl(name='y', quals=[], storage=[], funcspec=[], type=TypeDecl(declname='y', quals=[], - type=IdentifierType(names=['int'])), - init=Constant(type='int', value='0'), bitsize=None)]))]) + type=IdentifierType(names=['int'])), init=None, + bitsize=None)]), type=TypeDecl( + declname='foo', quals=[], type=IdentifierType(names=['int']))), + init=None, bitsize=None), param_decls=None, + body=Compound(block_items=[ + Assignment(op='=', lvalue=ID(name='y'), + rvalue=Constant(type='int', value='0'))]))]) -PARAMS = FileAST(ext=[ - FuncDef( - decl=Decl( - name='main', quals=[], storage=[], funcspec=[], - type=FuncDecl(args=ParamList(params=[ - Decl(name='x1', quals=[], storage=[], funcspec=[], - type=TypeDecl( - declname='x1', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Decl(name='x2', quals=[], storage=[], funcspec=[], - type=TypeDecl( - declname='x2', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None), - Decl(name='x3', quals=[], storage=[], funcspec=[], - type=TypeDecl( - declname='x3', quals=[], - type=IdentifierType(names=['int'])), - init=None, bitsize=None)]), - type=TypeDecl( - declname='main', quals=[], - type=IdentifierType(names=['int']))), init=None, - bitsize=None), - param_decls=None, - body=Compound(block_items=[Assignment( - op='=', lvalue=ID(name='x1'), - rvalue=Constant(type='int', value='1'))]) - )]) +PARAMS = FileAST(ext=[FuncDef(decl=Decl( + name='foo', quals=[], storage=[], funcspec=[], type=FuncDecl( + args=ParamList(params=[ + Decl(name='x1', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x1', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='x2', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x2', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None), + Decl(name='x3', quals=[], storage=[], funcspec=[], + type=TypeDecl(declname='x3', quals=[], + type=IdentifierType(names=['int'])), init=None, + bitsize=None)]), type=TypeDecl(declname='foo', quals=[], + type=IdentifierType( + names=['int']))), + init=None, bitsize=None), param_decls=None, + body=Compound(block_items=[ + Assignment(op='=', lvalue=ID(name='x1'), rvalue=ID(name='x2'))]))]) diff --git a/tests/mocks/decl_and_assign_value.c b/tests/mocks/decl_and_assign_value.c deleted file mode 100644 index 355bcb25..00000000 --- a/tests/mocks/decl_and_assign_value.c +++ /dev/null @@ -1,4 +0,0 @@ -int main(){ - int y; - y = 0; -} \ No newline at end of file diff --git a/tests/mocks/extra_braces.c b/tests/mocks/extra_braces.c deleted file mode 100644 index 8e71e4b6..00000000 --- a/tests/mocks/extra_braces.c +++ /dev/null @@ -1,7 +0,0 @@ -int main() { - int x; - int y; - { - if(x > y){x = y;} - } -} \ No newline at end of file diff --git a/tests/mocks/if_with_braces.c b/tests/mocks/if_with_braces.c index 82fbbcf0..aae15327 100644 --- a/tests/mocks/if_with_braces.c +++ b/tests/mocks/if_with_braces.c @@ -1,15 +1,6 @@ -int main() { - int x; - int y; - x = 1; - - int x1; - int x2; - int x3; - x1 = 1; - x2 = 2; +int foo(int x, int y, int x1, int x2, int x3) { if (x > 0) { - x3 = 1; + x3 = x1; } else { x3 = x2; diff --git a/tests/mocks/if_wo_braces.c b/tests/mocks/if_wo_braces.c index 582eb9cf..53f5547a 100644 --- a/tests/mocks/if_wo_braces.c +++ b/tests/mocks/if_wo_braces.c @@ -1,14 +1,5 @@ -int main() { - int x; - int y; - x = 1; - - int x1; - int x2; - int x3; - x1 = 1; - x2 = 2; - if (x > 0) x3 = 1; +int foo(int x, int y, int x1, int x2, int x3) { + if (x > 0) x3 = x1; else x3 = x2; y = x3; } \ No newline at end of file diff --git a/tests/mocks/params.c b/tests/mocks/params.c index def7343f..0fdb9f9b 100644 --- a/tests/mocks/params.c +++ b/tests/mocks/params.c @@ -1,3 +1,3 @@ -int main(int x1, int x2, int x3){ - x1 = 1; +int foo(int x1, int x2, int x3){ + x1 = x2; } \ No newline at end of file diff --git a/tests/mocks/variable_ignored.c b/tests/mocks/variable_ignored.c index a15146b1..090def64 100644 --- a/tests/mocks/variable_ignored.c +++ b/tests/mocks/variable_ignored.c @@ -1,4 +1,4 @@ -int main(){ +int foo(int X1, int X2, int X3, int X4){ X2 = X3+X1; X4 = X2; } \ No newline at end of file diff --git a/tests/test_analysis.py b/tests/test_analysis.py index c13c0468..0c241eca 100644 --- a/tests/test_analysis.py +++ b/tests/test_analysis.py @@ -1,10 +1,10 @@ from pymwp import Analysis, Polynomial from .mocks.ast_mocks import \ INFINITE_2C, NOT_INFINITE_2C, IF_WO_BRACES, IF_WITH_BRACES, \ - VARIABLE_IGNORED, EXTRA_BRACES, ASSIGN_VALUE_ONLY, PARAMS + VARIABLE_IGNORED, OTHER_BRACES_ISSUES, BASICS_ASSIGN_VALUE, PARAMS -def test_analyze_simple_infinite(): +def test_analyze_infinite2(): """Check analysis result for infinite/infinite_2.c""" relation, combinations, infty = Analysis.run(INFINITE_2C, no_save=True) @@ -13,7 +13,7 @@ def test_analyze_simple_infinite(): assert set(relation.variables) == {'X0', 'X1'} # expected variables -def test_analyze_simple_non_infinite(): +def test_analyze_non_infinite_2(): """Check analysis result for not_infinite/notinfinite_2.c""" relation, combinations, infty = Analysis.run(NOT_INFINITE_2C, no_save=True) @@ -31,41 +31,23 @@ def test_analyze_simple_non_infinite(): assert str(relation.matrix[0][0].list[2]) == 'w.delta(2,0)' -def test_analyze_if_with_braces(): - """If...else program using curly braces; result is 0-matrix.""" - relation, combinations = Analysis.run(IF_WITH_BRACES, no_save=True)[:2] +def test_analyze_if_braces_do_not_matter(): + """If...else block with single-statement, with or without curly braces, + should give the same analysis result.""" + rel_with, choices_with = Analysis.run(IF_WITH_BRACES, no_save=True)[:2] + rel_wo, choices_wo = Analysis.run(IF_WO_BRACES, no_save=True)[:2] # match choices and variables - assert set(relation.variables) == {'x', 'x1', 'x2', 'x3', 'y'} - assert combinations == [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], - [2, 0], [2, 1], [2, 2]] - # all monomials are 0s - try: - for i, _ in enumerate(relation.variables): - for j, _ in enumerate(relation.variables): - assert relation.matrix[i][j].list[0].scalar == 'o' - except AssertionError: - relation.show() - raise - - -def test_analyze_if_without_braces(): - """If...else program NOT using curly braces; result is 0-matrix, expect - exact same output as previous test.""" - relation, combinations = Analysis.run(IF_WO_BRACES, no_save=True)[:2] - - # match choices and variables - assert set(relation.variables) == {'x', 'x1', 'x2', 'x3', 'y'} - assert combinations == [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], - [2, 0], [2, 1], [2, 2]] - # all monomials are 0s - try: - for i, _ in enumerate(relation.variables): - for j, _ in enumerate(relation.variables): - assert relation.matrix[i][j].list[0].scalar == 'o' - except AssertionError: - relation.show() - raise + assert set(rel_with.variables) == set(rel_wo.variables) == \ + {'x', 'x1', 'x2', 'x3', 'y'} + # should give same choices + assert choices_with == choices_wo == \ + [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1], + [0, 1, 2], [0, 2, 0], [0, 2, 1], [0, 2, 2], [1, 0, 0], + [1, 0, 1], [1, 0, 2], [1, 1, 0], [1, 1, 1], [1, 1, 2], + [1, 2, 0], [1, 2, 1], [1, 2, 2], [2, 0, 0], [2, 0, 1], + [2, 0, 2], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 2, 0], + [2, 2, 1], [2, 2, 2]] def test_analyze_variable_ignore(): @@ -82,9 +64,9 @@ def test_analyze_variable_ignore(): o = '+o' m = '+m' res = [ + [m, wpm, o, wpm], [o, o, o, o], - [wmp, m, o, wmp], - [wpm, o, m, wpm], + [o, wmp, m, wmp], [o, o, o, o], ] @@ -100,7 +82,8 @@ def test_analyze_variable_ignore(): def test_extra_braces_are_ignored(): """Analysis ignores superfluous braces in C program, see issue: #25: https://github.com/seiller/pymwp/issues/25""" - relation, combinations = Analysis.run(EXTRA_BRACES, no_save=True)[:2] + relation, combinations = Analysis.run(OTHER_BRACES_ISSUES, no_save=True)[ + :2] assert set(relation.variables) == {'x', 'y'} assert relation.matrix[0][0] == Polynomial('m') @@ -113,10 +96,10 @@ def test_assigning_value_yields_matrix_result(): """Analyzing should yield a result with matrix for programs with declaration only. issue #43: https://github.com/seiller/pymwp/issues/43""" - relation, combinations = Analysis.run(ASSIGN_VALUE_ONLY, no_save=True)[:2] + relation = Analysis.run(BASICS_ASSIGN_VALUE, no_save=True)[0] assert relation.variables == ['y'] - assert relation.matrix[0][0] == Polynomial('m') + assert relation.matrix[0][0] == Polynomial('o') def test_analysis_identifies_function_params():