1 | % (c) 2015-2024 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, | |
2 | % Heinrich Heine Universitaet Duesseldorf | |
3 | % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) | |
4 | ||
5 | :- module(prob_state_predicates, [create_state_pred/4, create_state_pred/5]). | |
6 | ||
7 | :- use_module(library(lists), [maplist/2]). | |
8 | ||
9 | :- use_module(probsrc(bsyntaxtree), [safe_create_texpr/3, | |
10 | conjunct_predicates/2]). | |
11 | :- use_module(probsrc(translate), [translate_bexpression/2]). | |
12 | :- use_module(probsrc(debug), [debug_format/3]). | |
13 | :- use_module(probsrc(kernel_tools),[ground_value/1]). | |
14 | :- use_module(probsrc(b_global_sets), [is_b_global_constant/3]). | |
15 | :- use_module(probsrc(custom_explicit_sets), [expand_custom_set_to_list_now/2]). | |
16 | :- use_module(probsrc(clpfd_interface), [clpfd_domain/3]). | |
17 | :- use_module(probsrc(error_manager), [add_error/4]). | |
18 | ||
19 | :- use_module(probsrc(module_information),[module_info/2]). | |
20 | :- module_info(group,smt_solvers). | |
21 | :- module_info(description,'This module translates ProB\'s (local) states to predicates understandable for CVC4/Z3'). | |
22 | ||
23 | create_state_pred(IDs,LS,S,P) :- | |
24 | create_state_pred(IDs,LS,S,P,[allow_to_skip_vars(_)]). | |
25 | ||
26 | create_state_pred(IDs,LS,S,P,Opts) :- | |
27 | create_state_preds(IDs,LS,S,Preds,Opts), | |
28 | conjunct_predicates(Preds,P), | |
29 | translate_bexpression(P,PP), | |
30 | debug_format(9,'smt_solvers_interface state_pred: ~w~n', [PP]). | |
31 | create_state_preds([],_,_,[b(truth,pred,[])],_). | |
32 | create_state_preds([b(identifier(Name),Type,Infos)|IDs],LS,S,[SubPred|Preds],Opts) :- | |
33 | ( member(bind(Name,Value),LS) | |
34 | ; member(bind(Name,Value),S) | |
35 | ),!, | |
36 | create_state_preds_aux(Name,Type,Infos,Value,SubPred,Opts), | |
37 | create_state_preds(IDs,LS,S,Preds,Opts). | |
38 | create_state_preds([_|IDs],LS,S,Preds,Opts) :- | |
39 | create_state_preds(IDs,LS,S,Preds,Opts). | |
40 | ||
41 | % for integers: create fd interval | |
42 | create_state_preds_aux(Name,integer,Infos,int(Value),Pred,_) :- !, | |
43 | (number(Value) -> | |
44 | safe_create_texpr(integer(Value),integer,TVal), | |
45 | safe_create_texpr(equal(b(identifier(Name),integer,Infos),TVal),pred,Pred) | |
46 | ; | |
47 | clpfd_domain(Value,Min,Max), | |
48 | (number(Min) | |
49 | -> safe_create_texpr(integer(Min),integer,MinValue), | |
50 | safe_create_texpr(greater_equal(b(identifier(Name),integer,Infos),MinValue),pred,Greater) | |
51 | ; Greater = b(truth,pred,[])), | |
52 | (number(Max) | |
53 | -> safe_create_texpr(integer(Max),integer,MaxValue), | |
54 | safe_create_texpr(less_equal(b(identifier(Name),integer,Infos),MaxValue),pred,Less) | |
55 | ; Less = b(truth,pred,[])), | |
56 | conjunct_predicates([Less,Greater],Pred) | |
57 | ). | |
58 | % non-integers: create equality if ground and simple enough | |
59 | create_state_preds_aux(Name,Type,Infos,Value,Pred,_) :- | |
60 | ground_value(Value), | |
61 | useful_value_for_state_pred(Value), !, | |
62 | Pred = b(equal(b(identifier(Name),Type,Infos),b(value(Value),Type,[])),pred,[]). | |
63 | % else: create truth (i.e. no futher state information) | |
64 | create_state_preds_aux(ID,_,_,Val,b(truth,pred,[]),Opts) :- | |
65 | (var(Val) % for :z3 these are the quantified variables themselves; in general we should ensure there are no constraints, co-routines pending on Val | |
66 | ; member(allow_to_skip_vars(true),Opts) | |
67 | -> debug_format(19,'Not creating state predicate for ~w (value too complex)~n',[ID]) | |
68 | ; member(skipped_variables(L),Opts), member(ID,L) | |
69 | -> debug_format(19,'Not creating state predicate for ~w (value too complex)~n',[ID]) | |
70 | ), | |
71 | !. | |
72 | create_state_preds_aux(ID,_,Infos,Val,b(truth,pred,[]),_) :- | |
73 | translate:print_bvalue(Val),nl, | |
74 | add_error(create_state_pred,'Ignoring value (too complex) for identifier',ID,Infos). % TO DO: enum warning ; if no solution found ok | |
75 | ||
76 | ||
77 | useful_value_for_state_pred([]). % empty sets | |
78 | useful_value_for_state_pred([H|T]) :- % sets as lists | |
79 | maplist(useful_value_for_state_pred,[H|T]). | |
80 | useful_value_for_state_pred(avl_set(Val)) :- | |
81 | expand_custom_set_to_list_now(avl_set(Val),Values), | |
82 | maplist(useful_value_for_state_pred,Values). | |
83 | useful_value_for_state_pred(int(Nr)) :- number(Nr). | |
84 | useful_value_for_state_pred(term(floating(Nr))) :- number(Nr). | |
85 | useful_value_for_state_pred(pred_true). | |
86 | useful_value_for_state_pred(pred_false). | |
87 | useful_value_for_state_pred(global_set(_)). | |
88 | useful_value_for_state_pred(fd(Num,Name)) :- | |
89 | is_b_global_constant(Name,Num,_). | |
90 | %useful_value_for_state_pred(rec(Fields)) :- useful_fields(Fields). % mk_value failed for test 1719 if we comment this in | |
91 | useful_value_for_state_pred((A,B)) :- | |
92 | useful_value_for_state_pred(A), | |
93 | useful_value_for_state_pred(B). | |
94 | ||
95 | %useful_fields([]). | |
96 | %useful_fields([field(_,Val)|T]) :- useful_value_for_state_pred(Val),useful_fields(T). |