| 1 | % evaluation of ProB AST integer expressions | |
| 2 | ||
| 3 | :- use_module(library(lists),[is_list/1,min_member/2,max_member/2]). | |
| 4 | :- use_module(library(avl),[avl_to_list/2,list_to_avl/2]). | |
| 5 | ||
| 6 | % return integer ast node | |
| 7 | int_prob(Expression,b(integer(Value),integer,[])) :- | |
| 8 | int(Expression,Value). | |
| 9 | ||
| 10 | % return prolog value | |
| 11 | int(b(Expression,_,_),Value) :- | |
| 12 | Expression =.. [Type,_,_] , | |
| 13 | member(Type,[add,minus,multiplication,div,power_of,modulo]) , | |
| 14 | % catch too big numbers or evaluation errors | |
| 15 | (on_exception(_,eval(b(Expression,_,_),Value),fail) | |
| 16 | -> true | |
| 17 | ; int(b(max_int,_,_),Value)). | |
| 18 | ||
| 19 | int(b(max_int,_,_),3). | |
| 20 | /*preferences:get_preference(maxint,Max).*/ | |
| 21 | int(b(min_int,_,_),-1). | |
| 22 | /*preferences:get_preference(minint,Min).*/ | |
| 23 | ||
| 24 | int(b(integer(Value),_,_),Value). | |
| 25 | ||
| 26 | int(int(Value),Value). | |
| 27 | ||
| 28 | int(b(card(Set),_,_),Value) :- | |
| 29 | sint(Set,ValueSet) , | |
| 30 | length(ValueSet,Value). | |
| 31 | ||
| 32 | int(b(unary_minus(Expr),_,_),Value) :- | |
| 33 | int(Expr,Temp) , | |
| 34 | Value is -(Temp). | |
| 35 | ||
| 36 | % prob ast sets | |
| 37 | % not-well-defined for empty set | |
| 38 | int(b(max(b(set_extension([]),set(_),_)),integer,_),0). | |
| 39 | int(b(min(b(set_extension([]),set(_),_)),integer,_),0). | |
| 40 | int(b(max(b(set_extension(ProBValueList),set(integer),_)),integer,_),Max) :- | |
| 41 | maplist(ast_to_value,ProBValueList,List) , | |
| 42 | max_member(Max,List). | |
| 43 | int(b(min(b(set_extension(ProBValueList),set(integer),_)),integer,_),Min) :- | |
| 44 | maplist(ast_to_value,ProBValueList,List) , | |
| 45 | min_member(Min,List). | |
| 46 | ||
| 47 | % prob value sets | |
| 48 | % also interpret max, min of empty sets for shrinking of | |
| 49 | % not well defined integer expressions | |
| 50 | int(b(max(b(value([]),set(integer),[])),integer,[]),0). | |
| 51 | int(b(min(b(value([]),set(integer),[])),integer,[]),0). | |
| 52 | ||
| 53 | int(b(max(b(value(avl_set(empty)),set(integer),[])),integer,[]),0). | |
| 54 | int(b(min(b(value(avl_set(empty)),set(integer),[])),integer,[]),0). | |
| 55 | % list set | |
| 56 | int(b(max(b(value(Set),set(integer),_)),integer,_),Max) :- | |
| 57 | is_list(Set) , | |
| 58 | max_member(MaxMem,Set) , | |
| 59 | MaxMem = int(Max). | |
| 60 | int(b(min(b(value(Set),set(integer),_)),integer,_),Min) :- | |
| 61 | is_list(Set) , | |
| 62 | min_member(MinMem,Set) , | |
| 63 | MinMem = int(Min). | |
| 64 | ||
| 65 | % avl set | |
| 66 | int(b(max(b(value(avl_set(Set)),set(integer),_)),integer,_),Max) :- | |
| 67 | avl_to_list(Set,Temp) , | |
| 68 | findall(Key,member(Key-_,Temp),List) , | |
| 69 | max_member(MaxMem,List) , | |
| 70 | MaxMem = int(Max). | |
| 71 | int(b(min(b(value(avl_set(Set)),set(integer),_)),integer,_),Min) :- | |
| 72 | avl_to_list(Set,Temp) , | |
| 73 | findall(Key,member(Key-_,Temp),List) , | |
| 74 | min_member(MinMem,List) , | |
| 75 | MinMem = int(Min). | |
| 76 | ||
| 77 | % evaluation | |
| 78 | eval(b(add(Expr1,Expr2),_,_),Value) :- | |
| 79 | int(Expr1,Value1) , | |
| 80 | int(Expr2,Value2) , | |
| 81 | Value is Value1 + Value2. | |
| 82 | eval(b(minus(Expr1,Expr2),_,_),Value) :- | |
| 83 | int(Expr1,Value1) , | |
| 84 | int(Expr2,Value2) , | |
| 85 | Value is Value1 - Value2. | |
| 86 | eval(b(multiplication(Expr1,Expr2),_,_),Value) :- | |
| 87 | int(Expr1,Value1) , | |
| 88 | int(Expr2,Value2) , | |
| 89 | Value is Value1 * Value2. | |
| 90 | eval(b(div(Expr1,Expr2),_,_),Value) :- | |
| 91 | int(Expr1,Value1) , | |
| 92 | int(Expr2,Value2) , | |
| 93 | % round values to be able to interpret not-well-defined expressions | |
| 94 | % so shrinking will be accepted by ProB interpreter | |
| 95 | %Value is round(Value1 / Value2). | |
| 96 | Value is Value1 / Value2. | |
| 97 | eval(b(modulo(Expr1,Expr2),_,_),Value) :- | |
| 98 | int(Expr1,Temp1) , Value1 is integer(Temp1) , % meanwhile bugfix (see thesis, chapter 2): | |
| 99 | int(Expr2,Temp2) , Value2 is integer(Temp2) , % problem with mod(0.0,_) in SICStus 4.3.1 implementation, so integer/1 fixes the issue | |
| 100 | Value is mod(Value1,Value2). | |
| 101 | eval(b(power_of(Expr1,Expr2),_,_),Value) :- | |
| 102 | int(Expr1,Value1) , | |
| 103 | int(Expr2,Value2) , | |
| 104 | Value is Value1 ^ Value2. |