create_top_level_wd_po(function(A,B),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
(get_texpr_type(B,TB),
safe_create_texpr(domain(A),set(TB),[],DomA),
safe_create_texpr(member(B,DomA),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged)
%, tools_printing:print_term_summary(created_function_po(Target,PO))
;
create_partial_fun_target(A,Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged)
).
create_top_level_wd_po(div(_,B),integer,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_texpr(integer(0),integer,[],Zero),
safe_create_texpr(not_equal(B,Zero),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(div_real(_,B),real,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_texpr(real('0.0'),real,[],Zero),
safe_create_texpr(not_equal(B,Zero),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(floored_div(_,B),integer,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_texpr(integer(0),integer,[],Zero),
safe_create_texpr(not_equal(B,Zero),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(modulo(A,B),integer,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_texpr(integer(0),integer,[],Zero),
( safe_create_texpr(greater(B,Zero),pred,[],Target), % does TLA require this to be positive??
create_po(Hypotheses,Target,Infos,Options,PO,Discharged)
; \+ z_or_tla_minor_mode,
safe_create_texpr(greater_equal(A,Zero),pred,[],Target), % in B A must be positive
create_po(Hypotheses,Target,Infos,Options,PO,Discharged)
).
create_top_level_wd_po(power_of(A,B),integer,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_texpr(integer(0),integer,[],Zero),
( AB=B, % B >= 0 must hold in B and Event-B
safe_create_texpr(greater_equal(AB,Zero),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged)
; eventb_mode, % TO DO: what happens in Z and TLA+?
AB=A, % A >= 0 must hold in Event-B
safe_create_texpr(greater_equal(AB,Zero),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged)
).
create_top_level_wd_po(power_of_real(A,B),real,Infos,Hypotheses,Options,PO,Discharged) :- !,
% power_of_real has a WD condition, real ** integer has not
create_texpr(real('0.0'),real,[],Zero),
( % A < 0 => real(floor(B))=B
safe_create_texpr(less_real(A,Zero),pred,[],LHS),
safe_create_texpr(convert_int_floor(B),integer,[],FloorB),
safe_create_texpr(convert_real(FloorB),real,[],BB),
safe_create_texpr(equal(B,BB),pred,[],RHS),
safe_create_texpr(implication(LHS,RHS),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged)
; % A = 0 => B >= 0
safe_create_texpr(equal(A,Zero),pred,[],LHS),
safe_create_texpr(less_equal_real(Zero,B),pred,[],RHS),
safe_create_texpr(implication(LHS,RHS),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged)
).
create_top_level_wd_po(iteration(_Rel,Index),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_texpr(integer(0),integer,[],Zero),
safe_create_texpr(greater_equal(Index,Zero),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(card(S),integer,Infos,Hypotheses,Options,PO,Discharged) :-
!,
\+ skip_finite_pos(Options),
safe_create_texpr(finite(S),pred,[contains_wd_condition],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(max(S),integer,Infos,Hypotheses,Options,PO,Discharged) :- !,
get_texpr_type(S,TS),
safe_create_texpr(not_equal(S,b(empty_set,TS,[])),pred,[],Target1),
( skip_finite_pos(Options)
-> Target = Target1
; safe_create_texpr(finite(S),pred,[contains_wd_condition],Target2),
conjunct_predicates([Target1,Target2],Target) % this is a sufficient condition, not a necessary one
),
% create a single PO, because of use in check_top_level_wd
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(min(S),integer,Infos,Hypotheses,Options,PO,Discharged) :- !,
get_texpr_type(S,TS),
safe_create_texpr(not_equal(S,b(empty_set,TS,[])),pred,[],Target1),
( skip_finite_pos(Options)
-> Target = Target1
; safe_create_texpr(finite(S),pred,[contains_wd_condition],Target2),
conjunct_predicates([Target1,Target2],Target) % this is a sufficient condition, not a necessary one
),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(max_real(S),real,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_top_level_wd_po(max(S),integer,Infos,Hypotheses,Options,PO,Discharged). % create same PO as for integer max
create_top_level_wd_po(min_real(S),real,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_top_level_wd_po(min(S),integer,Infos,Hypotheses,Options,PO,Discharged). % ditto
create_top_level_wd_po(general_intersection(A),TA,Infos,Hypotheses,Options,PO,Discharged) :- !, % inter
safe_create_texpr(not_equal(A,b(empty_set,set(TA),[])),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(size(S),integer,Infos,Hypotheses,Options,PO,Discharged) :- !,
% we do not have to create a finite PO: sequences are by construction finite
create_sequence_target(S,Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(insert_tail(S,_),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_sequence_target(S,Target), create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(insert_front(_,S),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
% page 174 of Abrial's book just requires that S is a partial function NATURAL1 +-> TYPE
create_sequence_target(S,Target), create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(rev(S),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_sequence_target(S,Target), create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(concat(S1,S2),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
(create_sequence_target(S1,Target) ; create_sequence_target(S2,Target)),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(general_concat(S),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_seq_seq_target(S,Target), create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(first(S),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_sequence1_target(S,Target), create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(last(S),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_sequence1_target(S,Target), create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(front(S),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_sequence1_target(S,Target), create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(tail(S),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_sequence1_target(S,Target), create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(restrict_front(S,N),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
( create_sequence_target(S,Target) ; create_seq_interval_target(S,N,Target) ),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(restrict_tail(S,N),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
( create_sequence_target(S,Target) ; create_seq_interval_target(S,N,Target) ),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(mu(S),_,Infos,Hypotheses,Options,PO,Discharged) :- !, % Z MU Operator
get_texpr_type(S,TS),
safe_create_texpr(not_equal(S,b(empty_set,TS,[])),pred,[],Target1),
create_texpr(integer(1),integer,[],One),
safe_create_texpr(card(S),integer,[contains_wd_condition],CardS),
safe_create_texpr(less_equal(CardS,One),pred,[],Target2),
( skip_finite_pos(Options)
-> conjunct_predicates([Target1,Target2],Target)
; safe_create_texpr(finite(S),pred,[contains_wd_condition],Target3),
conjunct_predicates([Target1,Target3,Target2],Target)
),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(external_function_call('MU',[S]),T,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_top_level_wd_po(mu(S),T,Infos,Hypotheses,Options,PO,Discharged).
create_top_level_wd_po(external_function_call('CHOOSE',[A]),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
get_texpr_type(A,TA),
safe_create_texpr(not_equal(A,b(empty_set,set(TA),[])),pred,[],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(external_function_call('SQUASH',[A]),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_partial_fun_target(A,Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(external_function_call(C,_),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
% external_fun_has_wd_condition is true
get_preference(wd_ignore_external_funs,false),
create_po(Hypotheses,b(unknown_truth_value(C),pred,[]),Infos,Options,PO,Discharged).
create_top_level_wd_po(external_subst_call(C,_),_,Infos,Hypotheses,Options,PO,Discharged) :- !, % ditto
get_preference(wd_ignore_external_funs,false),
create_po(Hypotheses,b(unknown_truth_value(C),pred,[]),Infos,Options,PO,Discharged).
create_top_level_wd_po(external_pred_call(C,_),_,Infos,Hypotheses,Options,PO,Discharged) :- !, % ditto
get_preference(wd_ignore_external_funs,false),
create_po(Hypotheses,b(unknown_truth_value(C),pred,[]),Infos,Options,PO,Discharged).
create_top_level_wd_po(general_product(Ids,P,E),Type,Infos,Hypotheses,Options,PO,Discharged) :- !,
create_top_level_wd_po(general_sum(Ids,P,E),Type,Infos,Hypotheses,Options,PO,Discharged).
create_top_level_wd_po(general_sum(Ids,P,_E),_,Infos,Hypotheses,Options,PO,Discharged) :- !,
\+ skip_finite_pos(Options),
create_comprehension_set(Ids,P,[],TS),
safe_create_texpr(finite(TS),pred,[contains_wd_condition],Target),
create_po(Hypotheses,Target,Infos,Options,PO,Discharged).
create_top_level_wd_po(Expr,T,I,Hypotheses,Options,PO,Discharged) :-
functor(Expr,F,N),
ajoin(['Unsupported expression ',F,'/',N,': '],Msg),
(ord_member_nonvar_chk(create_not_discharged_msg(MsgType),Options)
-> (MsgType=silent -> true ; add_message(well_def_analyser,Msg,Expr,I)) % we create warning below
; known_to_be_unsupported(F,N)
-> add_warning(well_def_analyser,Msg,Expr,I)
; wd_transparent(Expr)
-> add_error(well_def_analyser,Msg,'transparent operator has no top-level WD condition',I)
; (wd_like_conjunction(Expr,_,_,_) ; Expr=disjunct(_,_))
-> add_error(well_def_analyser,Msg,'operator has no top-level WD condition',I)
; add_internal_error(Msg,create_top_level_wd_po(Expr,T,I,_,Options,PO,Discharged))
),
inc_counter(unsupported),
create_po(Hypotheses,b(unknown_truth_value(F),pred,[wd(Expr)]),I,Options,PO,Discharged).