| 1 | % (c) 2020-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(well_def_tools, [rename_norm_term/3, member_in_norm_conjunction/2, not_occurs/2, occurs/2]). | |
| 6 | ||
| 7 | :- use_module(probsrc(module_information),[module_info/2]). | |
| 8 | :- module_info(group,well_def_prover). | |
| 9 | :- module_info(description,'This module provides utilities for the WD prover.'). | |
| 10 | ||
| 11 | ||
| 12 | :- use_module(probsrc(debug)). | |
| 13 | % -------------------- | |
| 14 | % tools for normalized expressions: | |
| 15 | ||
| 16 | % check if a known/bound ID occurs in a normalized expression | |
| 17 | not_occurs(Expr,ID) :- (occurs(Expr,ID) -> debug_println(19,occurs_in(ID,Expr)),fail ; true). | |
| 18 | occurs('$'(ID1),ID2) :- !, ID1 = ID2. | |
| 19 | occurs(conjunct(A,B),ID) :- !, (occurs(A,ID) ; occurs(B,ID)). | |
| 20 | occurs(couple(A,B),ID) :- !, (occurs(A,ID) ; occurs(B,ID)). | |
| 21 | occurs(equal(A,B),ID) :- !, (occurs(A,ID) ; occurs(B,ID)). | |
| 22 | occurs(field(_,A),ID) :- !, occurs(A,ID). | |
| 23 | occurs(function(A,B),ID) :- !, (occurs(A,ID) ; occurs(B,ID)). | |
| 24 | occurs(interval(A,B),ID) :- !, (occurs(A,ID) ; occurs(B,ID)). | |
| 25 | occurs(member(A,B),ID) :- !, (occurs(A,ID) ; occurs(B,ID)). | |
| 26 | occurs(record_field(A,B),ID) :- !, (occurs(A,ID) ; occurs(B,ID)). | |
| 27 | occurs(value(_),_ID) :- !, fail. | |
| 28 | occurs(string(_),_ID) :- !, fail. | |
| 29 | occurs(reverse(A),ID) :- !, occurs(A,ID). | |
| 30 | occurs(domain(A),ID) :- !, occurs(A,ID). | |
| 31 | occurs(range(A),ID) :- !, occurs(A,ID). | |
| 32 | occurs(comprehension_set(Paras,Body),ID) :- !, | |
| 33 | (member('$'(ID),Paras) -> fail % ID becomes invisible | |
| 34 | ; occurs(Body,ID)). | |
| 35 | % TO DO: treat other bound IDs exists,... [but not crucial, as we err on the safe side here] | |
| 36 | occurs([H|T],ID) :- !, (occurs(H,ID) -> true ; occurs(T,ID)). | |
| 37 | occurs(boolean_true,_) :- !,fail. | |
| 38 | occurs(boolean_false,_) :- !,fail. | |
| 39 | occurs(empty_set,_) :- !,fail. | |
| 40 | occurs(Expr,ID) :- Expr =.. [_|Args], member(A,Args), occurs(A,ID). | |
| 41 | ||
| 42 | member_in_norm_conjunction(Pred,Pred). | |
| 43 | member_in_norm_conjunction(conjunct(A,B),Pred) :- | |
| 44 | member_in_norm_conjunction(A,Pred) ; member_in_norm_conjunction(B,Pred). | |
| 45 | ||
| 46 | ||
| 47 | :- use_module(library(lists),[exclude/3]). | |
| 48 | ||
| 49 | % apply a substitution to a normalised term: | |
| 50 | rename_norm_term('$'(X),Subst,Res) :- !, | |
| 51 | (member(rename(X,NewTerm),Subst) % TODO : use ord_member | |
| 52 | -> Res=NewTerm | |
| 53 | ; Res='$'(X)). | |
| 54 | rename_norm_term(conjunct(A,B),Subst,conjunct(SA,SB)) :- !, | |
| 55 | rename_norm_term(A,Subst,SA), rename_norm_term(B,Subst,SB). | |
| 56 | rename_norm_term(if_then_else(A,B,C),Subst,if_then_else(SA,SB,SC)) :- !, | |
| 57 | rename_norm_term(A,Subst,SA), rename_norm_term(B,Subst,SB), rename_norm_term(C,Subst,SC). | |
| 58 | rename_norm_term(equal(A,B),Subst,equal(SA,SB)) :- !, | |
| 59 | rename_norm_term(A,Subst,SA), rename_norm_term(B,Subst,SB). | |
| 60 | rename_norm_term(function(A,B),Subst,function(SA,SB)) :- !, | |
| 61 | rename_norm_term(A,Subst,SA), rename_norm_term(B,Subst,SB). | |
| 62 | rename_norm_term(field(F,B),Subst,field(F,SB)) :- !, | |
| 63 | rename_norm_term(B,Subst,SB). | |
| 64 | rename_norm_term(record_field(Rec,FieldName),Subst,record_field(Rec,FieldName)) :- !, | |
| 65 | rename_norm_term(Rec,Subst,Rec). | |
| 66 | rename_norm_term(member(A,B),Subst,member(SA,SB)) :- !, | |
| 67 | rename_norm_term(A,Subst,SA), rename_norm_term(B,Subst,SB). | |
| 68 | rename_norm_term(rec(F),Subst,rec(SF)) :- !, | |
| 69 | l_rename_norm_terms(F,Subst,SF). | |
| 70 | rename_norm_term(Nr,_,Res) :- simple_norm_term(Nr),!,Res=Nr. | |
| 71 | rename_norm_term(QOP,Subst,RQOP) :- | |
| 72 | quantified_op(QOP,Functor,Ids,Exprs,Bodies),!, | |
| 73 | l_rename_norm_terms(Exprs,Subst,RExprs), | |
| 74 | sort(Ids,SIds), | |
| 75 | % TO DO: also ensure Subst is sorted and use linear algo | |
| 76 | exclude(clash_with_new(SIds),Subst,NSubst), | |
| 77 | %print(clashing(SIds,Subst,NSubst,Bodies)),nl, | |
| 78 | l_rename_norm_terms(Bodies,NSubst,RBodies), | |
| 79 | quantified_op(RQOP,Functor,Ids,RExprs,RBodies). | |
| 80 | rename_norm_term(Term,Subst,RenTerm) :- functor(Term,BOP,2), bin_op(BOP),!, | |
| 81 | functor(RenTerm,BOP,2), | |
| 82 | arg(1,Term,A), arg(1,RenTerm,RA), rename_norm_term(A,Subst,RA), | |
| 83 | arg(2,Term,B), arg(2,RenTerm,RB), rename_norm_term(B,Subst,RB). | |
| 84 | rename_norm_term(Term,Subst,RenTerm) :- functor(Term,UOP,1), un_op(UOP),!, | |
| 85 | functor(RenTerm,UOP,1), | |
| 86 | arg(1,Term,A), arg(1,RenTerm,RA), rename_norm_term(A,Subst,RA). | |
| 87 | rename_norm_term(Term,Subst,RenTerm) :- list_op(Term,Kind,List),!, | |
| 88 | list_op(RenTerm,Kind,RList), | |
| 89 | l_rename_norm_terms(List,Subst,RList). | |
| 90 | rename_norm_term(A,_,_) :- print(uncovered_renaming(A)),nl,fail. | |
| 91 | ||
| 92 | % uncovered_renaming(external_function_call(STRING_CODES,[$(s)])) | |
| 93 | ||
| 94 | :- use_module(library(ordsets),[ord_member/2]). | |
| 95 | clash_with_new(SortedIDs,rename(ID,_)) :- ord_member($(ID),SortedIDs). | |
| 96 | ||
| 97 | l_rename_norm_terms([],_,[]). | |
| 98 | l_rename_norm_terms([H|T],Subst,[RH|RT]) :- | |
| 99 | rename_norm_term(H,Subst,RH),!, | |
| 100 | l_rename_norm_terms(T,Subst,RT). | |
| 101 | ||
| 102 | ||
| 103 | list_op(set_extension(L),set_extension,L). | |
| 104 | list_op(sequence_extension(L),sequence_extension,L). | |
| 105 | list_op(external_function_call(Name,Args),external_function_call(Name),Args). | |
| 106 | ||
| 107 | % quantified_op(Term, ListOfDollarIDs, ListOfExprsOutsideOfScope, ListExpressionInNewScope) | |
| 108 | quantified_op(comprehension_set(IDS,Body),comprehension_set,IDS,[],[Body]). | |
| 109 | quantified_op(exists(IDS,Body),exists,IDS,[],[Body]). | |
| 110 | quantified_op(forall(IDS,LHS,RHS),forall,IDS,[],[LHS,RHS]). | |
| 111 | quantified_op(let_expression(IDS,Exprs,Body),let_expression,IDS,Exprs,[Body]). | |
| 112 | quantified_op(let_predicate(IDS,Exprs,Body),let_predicate,IDS,Exprs,[Body]). | |
| 113 | quantified_op(general_product(IDS,P,E),general_product,IDS,[],[P,E]). | |
| 114 | quantified_op(general_sum(IDS,P,E),general_sum,IDS,[],[P,E]). | |
| 115 | % lazy_let_pred, ... | |
| 116 | ||
| 117 | ||
| 118 | % TO DO: add more bin and unary ops; records, quantified operators | |
| 119 | bin_op(add). | |
| 120 | bin_op(add_real). | |
| 121 | bin_op(card). | |
| 122 | bin_op(cartesian_product). | |
| 123 | bin_op(composition). | |
| 124 | bin_op(concat). | |
| 125 | bin_op(couple). | |
| 126 | bin_op(div). | |
| 127 | bin_op(div_real). | |
| 128 | bin_op(disjunct). | |
| 129 | bin_op(domain_restriction). | |
| 130 | bin_op(domain_subtraction). | |
| 131 | bin_op(equivalence). | |
| 132 | bin_op(greater). | |
| 133 | bin_op(greater_equal). | |
| 134 | bin_op(floored_div). | |
| 135 | bin_op(function). | |
| 136 | bin_op(image). | |
| 137 | bin_op(implication). | |
| 138 | bin_op(insert_front). | |
| 139 | bin_op(insert_tail). | |
| 140 | bin_op(intersection). | |
| 141 | bin_op(interval). | |
| 142 | bin_op(iteration). | |
| 143 | bin_op(less). | |
| 144 | bin_op(less_equal). | |
| 145 | bin_op(less_real). | |
| 146 | bin_op(less_equal_real). | |
| 147 | bin_op(minus). | |
| 148 | bin_op(minus_real). | |
| 149 | bin_op(modulo). | |
| 150 | bin_op(multiplication). | |
| 151 | bin_op(multiplication_real). | |
| 152 | bin_op(overwrite). | |
| 153 | bin_op(not_equal). | |
| 154 | bin_op(not_member). | |
| 155 | bin_op(partial_bijection). | |
| 156 | bin_op(partial_function). | |
| 157 | bin_op(partial_injection). | |
| 158 | bin_op(partial_surjection). | |
| 159 | bin_op(power_of). | |
| 160 | bin_op(power_of_real). | |
| 161 | bin_op(range_restriction). | |
| 162 | bin_op(range_subtraction). | |
| 163 | bin_op(relations). | |
| 164 | bin_op(restrict_front). | |
| 165 | bin_op(restrict_tail). | |
| 166 | bin_op(set_subtraction). | |
| 167 | bin_op(size). | |
| 168 | bin_op(subset). | |
| 169 | bin_op(subset_strict). | |
| 170 | bin_op(surjection_relation). | |
| 171 | bin_op(total_function). | |
| 172 | bin_op(total_injection). | |
| 173 | bin_op(total_surjection). | |
| 174 | bin_op(total_relation). | |
| 175 | bin_op(total_surjection_relation). | |
| 176 | bin_op(union). | |
| 177 | ||
| 178 | un_op(bag_items). | |
| 179 | un_op(card). | |
| 180 | un_op(closure). % closure1 | |
| 181 | un_op(compaction). | |
| 182 | un_op(convert_bool). | |
| 183 | un_op(convert_real). | |
| 184 | un_op(convert_int_floor). | |
| 185 | un_op(convert_int_ceiling). | |
| 186 | un_op(domain). | |
| 187 | un_op(finite). | |
| 188 | un_op(fin_subset). | |
| 189 | un_op(fin1_subset). | |
| 190 | un_op(first_of_pair). | |
| 191 | un_op(front). | |
| 192 | un_op(identity). | |
| 193 | un_op(iseq). | |
| 194 | un_op(iseq1). | |
| 195 | un_op(last). | |
| 196 | un_op(negation). | |
| 197 | un_op(max). | |
| 198 | un_op(max_real). | |
| 199 | un_op(min). | |
| 200 | un_op(min_real). | |
| 201 | un_op(mu). | |
| 202 | un_op(perm). | |
| 203 | un_op(pow_subset). | |
| 204 | un_op(pow1_subset). | |
| 205 | un_op(range). | |
| 206 | un_op(rev). | |
| 207 | un_op(reverse). | |
| 208 | un_op(reflexive_closure). | |
| 209 | un_op(second_of_pair). | |
| 210 | un_op(seq). | |
| 211 | un_op(seq1). | |
| 212 | un_op(size). | |
| 213 | un_op(tail). | |
| 214 | un_op(unary_minus). | |
| 215 | un_op(unary_minus_real). | |
| 216 | ||
| 217 | % do not require renaming: | |
| 218 | simple_norm_term(truth). | |
| 219 | simple_norm_term(boolean_true). | |
| 220 | simple_norm_term(boolean_false). | |
| 221 | simple_norm_term(bool_set). | |
| 222 | simple_norm_term(float_set). | |
| 223 | simple_norm_term(real_set). | |
| 224 | simple_norm_term(string_set). | |
| 225 | simple_norm_term(typeset). | |
| 226 | simple_norm_term(value(_)). | |
| 227 | simple_norm_term(string(_)). | |
| 228 | simple_norm_term(empty_set). | |
| 229 | simple_norm_term(empty_sequence). | |
| 230 | simple_norm_term(max_int). | |
| 231 | simple_norm_term(min_int). | |
| 232 | simple_norm_term('NATURAL'). | |
| 233 | simple_norm_term('NATURAL1'). | |
| 234 | simple_norm_term(lazy_lookup_pred(_)). | |
| 235 | simple_norm_term(lazy_lookup_expr(_)). | |
| 236 | simple_norm_term(Nr) :- number(Nr). |