| 1 | % Heinrich Heine Universitaet Duesseldorf | |
| 2 | % (c) 2025-2026 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, | |
| 3 | % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) | |
| 4 | ||
| 5 | ||
| 6 | :- module(simplification_rules,[simplification_rule/6, is_true/1]). | |
| 7 | ||
| 8 | ||
| 9 | :- use_module(probsrc(module_information),[module_info/2]). | |
| 10 | :- module_info(group,sequent_prover). | |
| 11 | :- module_info(description,'This module provides the simplification rules'). | |
| 12 | ||
| 13 | :- use_module(seqproversrc(prover_utils)). | |
| 14 | :- use_module(library(lists)). | |
| 15 | :- use_module(probsrc(tools),[list_intersection/3, list_difference/3]). | |
| 16 | ||
| 17 | simplification_rule(Goal,NewGoal,_,Rule,Descr,Info) :- | |
| 18 | simp_rule(Goal,NewGoal,Rule,level0,Descr,Info), | |
| 19 | Goal \= NewGoal. | |
| 20 | simplification_rule(Goal,NewGoal,Hyps,Rule,Descr,_Info) :- | |
| 21 | simp_rule_with_hyps(Goal,NewGoal,Rule,Hyps), | |
| 22 | create_descr(Rule,Goal,Descr), | |
| 23 | Goal \= NewGoal. | |
| 24 | ||
| 25 | ||
| 26 | ||
| 27 | is_true(equal(X,Y)) :- equal_terms(X,Y). % SIMP_MULTI_EQUAL | |
| 28 | is_true(less_equal(X,Y)) :- equal_terms(X,Y). % SIMP_MULTI_LT + SIMP_MULTI_GT | |
| 29 | is_true(greater_equal(X,Y)) :- equal_terms(X,Y). % SIMP_MULTI_LE + SIMP_MULTI_GE | |
| 30 | is_true(negation(falsity)). % SIMP_SPECIAL_NOT_BFALSE | |
| 31 | is_true(subset(empty_set,_)). % SIMP_SPECIAL_SUBSETEQ | |
| 32 | is_true(subset(S,T)) :- equal_terms(S,T). % SIMP_MULTI_SUBSETEQ | |
| 33 | is_true(implication(_P,truth)). % SIMP_SPECIAL_IMP_BTRUE_R | |
| 34 | is_true(implication(falsity,_P)). % SIMP_SPECIAL_IMP_BFALSE_L | |
| 35 | is_true(implication(P,Q)) :- equal_terms(P,Q). % SIMP_MULTI_IMP | |
| 36 | is_true(equivalence(P,Q)) :- equal_terms(P,Q). % SIMP_MULTI_EQV | |
| 37 | is_true(member(card(_S),Nat)) :- is_natural_set(Nat). % SIMP_CARD_NATURAL | |
| 38 | is_true(P) :- is_less_eq(P,0,card(_S)). % SIMP_LIT_LE_CARD_0 + SIMP_LIT_GE_CARD_0 | |
| 39 | is_true(member(min(S),T)) :- equal_terms(S,T). % SIMP_MIN_IN | |
| 40 | is_true(member(max(S),T)) :- equal_terms(S,T). % SIMP_MAX_IN | |
| 41 | is_true(member(couple(E,F),event_b_identity)) :- equal_terms(E,F). % SIMP_SPECIAL_IN_ID | |
| 42 | is_true(finite(bool_set)). % SIMP_FINITE_BOOL | |
| 43 | is_true(finite(set_extension(_))). % SIMP_FINITE_SETENUM | |
| 44 | is_true(finite(interval(_,_))). % SIMP_FINITE_UPTO | |
| 45 | is_true(finite(empty_set)). % SIMP_SPECIAL_FINITE | |
| 46 | is_true(member(I,Nat)) :- is_natural_set(Nat), number(I), I >= 0. % SIMP_LIT_IN_NATURAL | |
| 47 | is_true(member(I,Nat)) :- is_natural1_set(Nat), number(I), I >= 1. % SIMP_LIT_IN_NATURAL1 | |
| 48 | ||
| 49 | ||
| 50 | ||
| 51 | % simp_rule/6 | |
| 52 | simp_rule(X,NewX,Rule,Op,Descr,Info) :- | |
| 53 | (simp_rule(X,NewX,Rule) | |
| 54 | ; simp_rule(X,NewX,Rule,Op) | |
| 55 | ; simp_rule(X,NewX,Rule,Op,Info) | |
| 56 | ; simp_rule_with_info(X,NewX,Rule,Info)), | |
| 57 | create_descr(Rule,X,Descr). | |
| 58 | simp_rule(X,NewX,Rule,_,Descr,_) :- simp_rule_with_descr(X,NewX,Rule,Descr). | |
| 59 | simp_rule(Expr,Res,Expr,_,Descr,_) :- compute(Expr,Res), create_descr('Compute',Expr,Descr). | |
| 60 | % allow simplifications deeper inside the term: | |
| 61 | simp_rule(C,NewC,Rule,_,Descr,Info) :- C=..[F,P], simp_rule(P,Q,Rule,F,Descr,Info), NewC=..[F,Q]. | |
| 62 | simp_rule(C,NewC,Rule,_,Descr,Info) :- C=..[F,P,R], simp_rule(P,Q,Rule,F,Descr,Info), NewC=..[F,Q,R]. | |
| 63 | simp_rule(C,NewC,Rule,_,Descr,Info) :- C=..[F,R,P], simp_rule(P,Q,Rule,F,Descr,Info), NewC=..[F,R,Q]. | |
| 64 | ||
| 65 | ||
| 66 | compute(Expr,Res) :- evaluate(Expr,Res). | |
| 67 | ||
| 68 | evaluate(I,I) :- number(I). | |
| 69 | evaluate(add(I,J),Res) :- evaluate(I,NewI), evaluate(J,NewJ), Res is NewI + NewJ. | |
| 70 | evaluate(minus(I,J),Res) :- evaluate(I,NewI), evaluate(J,NewJ), Res is NewI - NewJ. | |
| 71 | evaluate(multiplication(I,J),Res) :- evaluate(I,NewI), evaluate(J,NewJ), Res is NewI * NewJ. | |
| 72 | evaluate(div(I,J),Res) :- evaluate(I,NewI), evaluate(J,NewJ), J =\= 0, Res is NewI // NewJ. | |
| 73 | evaluate(modulo(I,J),Res) :- evaluate(I,NewI), evaluate(J,NewJ), J =\= 0, Res is NewI mod NewJ. | |
| 74 | evaluate(power_of(I,J),Res) :- evaluate(I,NewI), evaluate(J,NewJ), Res is NewI ^ NewJ. | |
| 75 | ||
| 76 | ||
| 77 | % simp_rule/5 | |
| 78 | simp_rule(U,Ty,'SIMP_TYPE_BUNION',OuterOp,Info) :- OuterOp \= union, | |
| 79 | % S \/ ... Ty \/ ... T == Ty | |
| 80 | member_of_bin_op(union,Ty,U), type_expression(Ty,Info). | |
| 81 | simp_rule(overwrite(P,Q),Res,'SIMP_TYPE_OVERL_CPROD',OuterOp,Info) :- | |
| 82 | OuterOp \= overwrite, | |
| 83 | op_to_list(overwrite(P,Q),List,overwrite), | |
| 84 | overwrite_type(List,[],ResList,Info), | |
| 85 | list_to_op(ResList,Res,overwrite). | |
| 86 | ||
| 87 | % rules that do not require hyps: | |
| 88 | simp_rule(not_equal(L,L),falsity,'SIMP_MULTI_NOTEQUAL'). | |
| 89 | simp_rule(less_equal(I,J),Res,'SIMP_LIT_LE') :- number(I), number(J), (I =< J -> Res=truth ; Res=falsity). % where I and J are literals | |
| 90 | simp_rule(less(I,J),Res,'SIMP_LIT_LT') :- number(I), number(J), (I < J -> Res=truth ; Res=falsity). | |
| 91 | simp_rule(greater_equal(I,J),Res,'SIMP_LIT_GE') :- number(I), number(J), (I >= J -> Res=truth ; Res=falsity). | |
| 92 | simp_rule(greater(I,J),Res,'SIMP_LIT_GT') :- number(I), number(J), (I > J -> Res=truth ; Res=falsity). | |
| 93 | simp_rule(equal(I,J),Res,'SIMP_LIT_EQUAL') :- number(I), number(J), (I = J -> Res=truth ; Res=falsity). | |
| 94 | simp_rule(not_equal(L,R),negation(equal(L,R)),'SIMP_NOTEQUAL'). | |
| 95 | simp_rule(domain(event_b_comprehension_set(Ids,couple(E,_),P)),event_b_comprehension_set(Ids,E,P),'SIMP_DOM_LAMBDA'). | |
| 96 | simp_rule(range(event_b_comprehension_set(Ids,couple(_,F),P)),event_b_comprehension_set(Ids,F,P),'SIMP_RAN_LAMBDA'). | |
| 97 | simp_rule(NotEmpty,exists([X],member(X,Set)),'DEF_SPECIAL_NOT_EQUAL') :- | |
| 98 | (is_inequality(NotEmpty,Set,empty_set) ; NotEmpty = negation(subset(Set,empty_set))), | |
| 99 | new_identifier(Set,X). | |
| 100 | simp_rule(convert_bool(Eq),P,'SIMP_KBOOL_LIT_EQUAL_TRUE') :- is_equality(Eq,P,boolean_true). | |
| 101 | simp_rule(implication(truth,P),P,'SIMP_SPECIAL_IMP_BTRUE_L'). | |
| 102 | simp_rule(implication(P,falsity),negation(P),'SIMP_SPECIAL_IMP_BFALSE_R'). | |
| 103 | simp_rule(not_member(L,R),negation(member(L,R)),'SIMP_NOTIN'). | |
| 104 | simp_rule(not_subset_strict(L,R),negation(subset_strict(L,R)),'SIMP_NOTSUBSET'). | |
| 105 | simp_rule(not_subset(L,R),negation(subset(L,R)),'SIMP_NOTSUBSETEQ'). | |
| 106 | simp_rule(I,equal(E,boolean_true),'SIMP_SPECIAL_NOT_EQUAL_FALSE') :- is_inequality(I,E,boolean_false). % SIMP_SPECIAL_NOT_EQUAL_FALSE_L, SIMP_SPECIAL_NOT_EQUAL_FALSE_R | |
| 107 | simp_rule(I,equal(E,boolean_false),'SIMP_SPECIAL_NOT_EQUAL_TRUE') :- is_inequality(I,E,boolean_true). % SIMP_SPECIAL_NOT_EQUAL_TRUE_L, SIMP_SPECIAL_NOT_EQUAL_TRUE_R | |
| 108 | simp_rule(forall(X,P1,P2),Res,'SIMP_FORALL_AND') :- P2 = conjunct(_,_), distribute_forall(X,P1,P2,Res). | |
| 109 | simp_rule(exists(X,D),Res,'SIMP_EXISTS_OR') :- D = disjunct(_,_), distribute_exists(X,D,Res). | |
| 110 | simp_rule(exists(X,implication(P,Q)),implication(forall(X,truth,P),exists(X,Q)),'SIMP_EXISTS_IMP'). | |
| 111 | simp_rule(forall(L,P1,P2),forall(Used,P1,P2),'SIMP_FORALL') :- remove_unused_identifier(L,P1,Used). | |
| 112 | simp_rule(exists(L,P),exists(Used,P),'SIMP_EXISTS') :- remove_unused_identifier(L,P,Used). | |
| 113 | simp_rule(negation(forall(X,P1,P2)),exists(X,negation(implication(P1,P2))),'DERIV_NOT_FORALL'). | |
| 114 | simp_rule(negation(exists(X,P)),forall(X,truth,negation(P)),'DERIV_NOT_EXISTS'). | |
| 115 | simp_rule(event_b_comprehension_set(Ids,E,P),event_b_comprehension_set(Used,E,P),'SIMP_COMPSET') :- % own rule | |
| 116 | remove_unused_identifier(Ids,P,Used). | |
| 117 | simp_rule(equal(boolean_true,boolean_false),falsity,'SIMP_SPECIAL_EQUAL_TRUE'). | |
| 118 | simp_rule(equal(couple(E,F),couple(G,H)),conjunct(equal(E,G),equal(F,H)),'SIMP_EQUAL_MAPSTO'). | |
| 119 | simp_rule(equal(SetE,SetF),equal(E,F),'SIMP_EQUAL_SING') :- singleton_set(SetE,E),singleton_set(SetF,F). | |
| 120 | simp_rule(set_subtraction(S,S),empty_set,'SIMP_MULTI_SETMINUS'). | |
| 121 | simp_rule(set_subtraction(S,empty_set),S,'SIMP_SPECIAL_SETMINUS_R'). | |
| 122 | simp_rule(set_subtraction(empty_set,_),empty_set,'SIMP_SPECIAL_SETMINUS_L'). | |
| 123 | simp_rule(member(E,set_subtraction(_,set_extension(L))),falsity,'DERIV_MULTI_IN_SETMINUS') :- member(F,L), equal_terms(E,F). | |
| 124 | simp_rule(member(E,U),truth,'DERIV_MULTI_IN_BUNION') :- | |
| 125 | % E\in A\/...\/ {..., E,...} \/...\/ B == \btrue | |
| 126 | % U = union(_,_), this requirement is not necessary for soundness of the rule | |
| 127 | member_of(union,set_extension(L),U), | |
| 128 | member(F,L), | |
| 129 | equal_terms(E,F). | |
| 130 | simp_rule(convert_bool(truth),boolean_true,'SIMP_SPECIAL_KBOOL_BTRUE'). | |
| 131 | simp_rule(convert_bool(falsity),boolean_false,'SIMP_SPECIAL_KBOOL_BFALSE'). | |
| 132 | simp_rule(unary_minus(C),NewC,'DISTRI_MINUS') :- | |
| 133 | distribute_unary_minus(C,NewC). | |
| 134 | simp_rule(C,Res,'DISTRI_MINUS') :- | |
| 135 | distribute_binary_minus(C,NewC), | |
| 136 | left_associate_additions(NewC,Res). | |
| 137 | simp_rule(subset(Union,T),Res,'DISTRI_SUBSETEQ_BUNION_SING') :- | |
| 138 | member_of(union,SetF,Union), | |
| 139 | singleton_set(SetF,_), | |
| 140 | union_subset_member(T,Union,Res). | |
| 141 | simp_rule(finite(S),exists([N,F],member(F,total_bijection(interval(1,N),S))),'DEF_FINITE') :- | |
| 142 | new_identifier(S,N), | |
| 143 | new_function(S,F). | |
| 144 | simp_rule(finite(U),Conj,'SIMP_FINITE_BUNION') :- U = union(_,_), finite_union(U,Conj). % covers fin_bunion_r | |
| 145 | simp_rule(finite(pow_subset(S)),finite(S),'SIMP_FINITE_POW'). | |
| 146 | simp_rule(finite(cartesian_product(S,T)),disjunct(disjunct(equal(S,empty_set),equal(T,empty_set)),conjunct(finite(S),finite(T))),'DERIV_FINITE_CPROD'). | |
| 147 | simp_rule(finite(reverse(R)),finite(R),'SIMP_FINITE_CONVERSE'). | |
| 148 | simp_rule(finite(domain_restriction(E,event_b_identity)),finite(E),'SIMP_FINITE_ID_DOMRES'). | |
| 149 | simp_rule(finite(domain_restriction(E,event_b_first_projection_v2)),finite(E),'SIMP_FINITE_PRJ1_DOMRES'). | |
| 150 | simp_rule(finite(domain_restriction(E,event_b_second_projection_v2)),finite(E),'SIMP_FINITE_PRJ2_DOMRES'). | |
| 151 | simp_rule(finite(Nat),falsity,'SIMP_FINITE_NATURAL') :- is_natural_set(Nat). | |
| 152 | simp_rule(finite(Nat),falsity,'SIMP_FINITE_NATURAL1') :- is_natural1_set(Nat). | |
| 153 | simp_rule(finite(Z),falsity,'SIMP_FINITE_INTEGER') :- is_integer_set(Z). | |
| 154 | simp_rule(equivalence(A,B),P,'SIMP_SPECIAL_EQV_BTRUE') :- sym_unify(A,B,P,truth). | |
| 155 | simp_rule(equivalence(A,B),negation(P),'SIMP_SPECIAL_EQV_BFALSE') :- sym_unify(A,B,P,falsity). | |
| 156 | simp_rule(subset_strict(A,B),conjunct(subset(A,B),negation(equal(A,B))),'DEF_SUBSET'). | |
| 157 | simp_rule(subset_strict(_,empty_set),falsity,'SIMP_SPECIAL_SUBSET_R'). | |
| 158 | simp_rule(subset_strict(empty_set,S),negation(equal(S,empty_set)),'SIMP_SPECIAL_SUBSET_L'). | |
| 159 | simp_rule(subset_strict(S,T),falsity,'SIMP_MULTI_SUBSET') :- equal_terms(S,T). | |
| 160 | simp_rule(C,Res,'DISTRI_PROD_PLUS') :- distri(C,Res,multiplication,add). | |
| 161 | simp_rule(C,Res,'DISTRI_PROD_MINUS') :- distri(C,Res,multiplication,minus). | |
| 162 | simp_rule(C,Res,'DISTRI_AND_OR') :- distri(C,Res,conjunct,disjunct). | |
| 163 | simp_rule(C,Res,'DISTRI_OR_AND') :- distri(C,Res,disjunct,conjunct). | |
| 164 | simp_rule(implication(P,Q),implication(negation(Q),negation(P)),'DERIV_IMP'). | |
| 165 | simp_rule(implication(P,implication(Q,R)),implication(conjunct(P,Q),R),'DERIV_IMP_IMP'). | |
| 166 | simp_rule(implication(P,C),Res,'DISTRI_IMP_AND') :- C = conjunct(_,_), and_imp(C,P,Res,conjunct). | |
| 167 | simp_rule(implication(D,R),Res,'DISTRI_IMP_OR') :- D = disjunct(_,_), and_imp(D,R,Res,disjunct). | |
| 168 | simp_rule(equivalence(P,Q),conjunct(implication(P,Q),implication(Q,P)),'DEF_EQV'). | |
| 169 | simp_rule(C,P,'SIMP_SPECIAL_AND_BTRUE') :- C = conjunct(P,truth) ; C = conjunct(truth,P). | |
| 170 | simp_rule(D,P,'SIMP_SPECIAL_OR_BFALSE') :- D = disjunct(P,falsity) ; D = disjunct(falsity,P). | |
| 171 | simp_rule(implication(NotP,P),P,'SIMP_MULTI_IMP_NOT_L') :- is_negation(P,NotP). | |
| 172 | simp_rule(implication(P,NotP),NotP,'SIMP_MULTI_IMP_NOT_R') :- is_negation(P,NotP). | |
| 173 | simp_rule(equivalence(A,B),falsity,'SIMP_MULTI_EQV_NOT') :- sym_unify(A,B,P,NotP), is_negation(P,NotP). | |
| 174 | simp_rule(implication(C,Q),truth,'SIMP_MULTI_IMP_AND') :- | |
| 175 | % P & ... & Q & ... & R => Q == \btrue | |
| 176 | member_of(conjunct,Q,C). % TODO: will not select a conjunction for Q | |
| 177 | simp_rule(negation(truth),falsity,'SIMP_SPECIAL_NOT_BTRUE'). | |
| 178 | simp_rule(member(X,SetA),equal(X,A),'SIMP_IN_SING') :- | |
| 179 | singleton_set(SetA,A). | |
| 180 | simp_rule(subset(SetA,S),member(A,S),'SIMP_SUBSETEQ_SING') :- singleton_set(SetA,A). | |
| 181 | simp_rule(subset(Union,S),Conj,'DERIV_SUBSETEQ_BUNION') :- Union = union(_,_), union_subset(S,Union,Conj). | |
| 182 | simp_rule(subset(S,Inter),Conj,'DERIV_SUBSETEQ_BINTER') :- Inter = intersection(_,_), subset_inter(S,Inter,Conj). | |
| 183 | simp_rule(member(_,empty_set),falsity,'SIMP_SPECIAL_IN') . | |
| 184 | simp_rule(member(B,S),truth,'SIMP_MULTI_IN') :- S = set_extension(L), member(B,L). | |
| 185 | simp_rule(set_extension(L),set_extension(Res),'SIMP_MULTI_SETENUM') :- without_duplicates(L,Res). | |
| 186 | simp_rule(subset(S,U),truth,'SIMP_SUBSETEQ_BUNION') :- member_of(union,S,U). | |
| 187 | simp_rule(subset(I,S),truth,'SIMP_SUBSETEQ_BINTER') :- member_of(intersection,S,I). | |
| 188 | simp_rule(implication(C,negation(Q)),negation(C),'SIMP_MULTI_IMP_AND_NOT_R') :- member_of(conjunct,Q,C). | |
| 189 | simp_rule(implication(C,Q),negation(C),'SIMP_MULTI_IMP_AND_NOT_L') :- member_of(conjunct,negation(Q),C). | |
| 190 | simp_rule(U,S,'SIMP_SPECIAL_BUNION') :- U = union(S,empty_set) ; U = union(empty_set,S). | |
| 191 | simp_rule(R,set_extension([empty_set]),'SIMP_SPECIAL_EQUAL_RELDOMRAN') :- R=..[Op,empty_set,empty_set], | |
| 192 | member(Op,[total_surjection,total_bijection,total_surjection_relation]). | |
| 193 | simp_rule(domain(cartesian_product(E,F)),E,'SIMP_MULTI_DOM_CPROD') :- equal_terms(E,F). | |
| 194 | simp_rule(range(cartesian_product(E,F)),E,'SIMP_MULTI_RAN_CPROD') :- equal_terms(E,F). | |
| 195 | simp_rule(image(cartesian_product(SetE,S),SetF),S,'SIMP_MULTI_RELIMAGE_CPROD_SING') :- | |
| 196 | singleton_set(SetE,E), | |
| 197 | singleton_set(SetF,F), | |
| 198 | equal_terms(E,F). | |
| 199 | simp_rule(image(set_extension([couple(E,G)]),SetF),set_extension([G]),'SIMP_MULTI_RELIMAGE_SING_MAPSTO') :- | |
| 200 | singleton_set(SetF,F), | |
| 201 | equal_terms(E,F). | |
| 202 | simp_rule(domain(domain_restriction(A,F)),intersection(domain(F),A),'SIMP_MULTI_DOM_DOMRES'). | |
| 203 | simp_rule(domain(domain_subtraction(A,F)),set_subtraction(domain(F),A),'SIMP_MULTI_DOM_DOMSUB'). | |
| 204 | simp_rule(range(range_restriction(F,A)),intersection(range(F),A),'SIMP_MULTI_RAN_RANRES'). | |
| 205 | simp_rule(range(range_subtraction(F,A)),set_subtraction(range(F),A),'SIMP_MULTI_RAN_RANSUB'). | |
| 206 | simp_rule(M,exists([Y],member(couple(R,Y),F)),'DEF_IN_DOM') :- | |
| 207 | M = member(R,domain(F)), | |
| 208 | new_identifier(M,Y). | |
| 209 | simp_rule(M,exists([X],member(couple(X,R),F)),'DEF_IN_RAN') :- | |
| 210 | M = member(R,range(F)), | |
| 211 | new_identifier(M,X). | |
| 212 | simp_rule(member(couple(E,F),reverse(R)),member(couple(F,E),R),'DEF_IN_CONVERSE'). | |
| 213 | simp_rule(member(couple(E,F),domain_restriction(S,R)),conjunct(member(E,S),member(couple(E,F),R)),'DEF_IN_DOMRES'). | |
| 214 | simp_rule(member(couple(E,F),range_restriction(R,T)),conjunct(member(couple(E,F),R),member(F,T)),'DEF_IN_RANRES'). | |
| 215 | simp_rule(member(couple(E,F),domain_subtraction(S,R)),conjunct(not_member(E,S),member(couple(E,F),R)),'DEF_IN_DOMSUB'). | |
| 216 | simp_rule(member(couple(E,F),range_subtraction(R,T)),conjunct(member(couple(E,F),R),not_member(F,T)),'DEF_IN_RANSUB'). | |
| 217 | simp_rule(member(F,image(R,W)),exists([X],conjunct(member(X,W),member(couple(X,F),R))),'DEF_IN_RELIMAGE') :- | |
| 218 | new_identifier(image(R,W),X). | |
| 219 | simp_rule(M,exists(Ids,Res),'DEF_IN_FCOMP') :- | |
| 220 | M = member(couple(E,F),Comp), | |
| 221 | Comp = composition(_,_), | |
| 222 | op_to_list(Comp,List,composition), | |
| 223 | length(List,Length), | |
| 224 | L1 is Length - 1, | |
| 225 | new_identifiers(M,L1,Ids), | |
| 226 | member_couples(E,F,List,Ids,ConjList), | |
| 227 | list_to_op(ConjList,Res,conjunct). | |
| 228 | simp_rule(image(Comp,S),image(Q,image(P,S)),'DERIV_RELIMAGE_FCOMP') :- split_composition(Comp,P,Q). | |
| 229 | ||
| 230 | simp_rule(composition(SetEF,SetGH),set_extension([couple(E,H)]),'DERIV_FCOMP_SING') :- | |
| 231 | singleton_set(SetEF,couple(E,F)), | |
| 232 | singleton_set(SetGH,couple(G,H)), | |
| 233 | equal_terms(F,G). | |
| 234 | simp_rule(overwrite(P,Q),union(domain_subtraction(domain(Q),P),Q),'DEF_OVERL'). | |
| 235 | simp_rule(member(couple(E,F),event_b_identity),equal(E,F),'DEF_IN_ID'). | |
| 236 | simp_rule(member(couple(E,couple(F,G)),direct_product(P,Q)),conjunct(member(couple(E,F),P),member(couple(E,G),Q)),'DEF_IN_DPROD'). | |
| 237 | simp_rule(member(couple(couple(E,G),couple(F,H)),parallel_product(P,Q)),conjunct(member(couple(E,F),P),member(couple(G,H),Q)),'DEF_IN_PPROD'). | |
| 238 | simp_rule(member(R,relations(S,T)),subset(R,cartesian_product(S,T)),'DEF_IN_REL'). | |
| 239 | simp_rule(member(R,total_relation(S,T)),conjunct(member(R,relations(S,T)),equal(domain(R),S)),'DEF_IN_RELDOM'). | |
| 240 | simp_rule(member(R,surjection_relation(S,T)),conjunct(member(R,relations(S,T)),equal(range(R),T)),'DEF_IN_RELRAN'). | |
| 241 | simp_rule(member(R,total_surjection_relation(S,T)),conjunct(conjunct(member(R,relations(S,T)),equal(domain(R),S)),equal(range(R),T)),'DEF_IN_RELDOMRAN'). | |
| 242 | simp_rule(M,conjunct(Conj1,Conj2),'DEF_IN_FCT') :- | |
| 243 | M = member(F,partial_function(S,T)), | |
| 244 | Conj1 = member(F,relations(S,T)), | |
| 245 | new_identifiers(M,3,Ids), | |
| 246 | Ids = [X,Y,Z], | |
| 247 | Conj2 = forall(Ids,conjunct(member(couple(X,Y),F),member(couple(X,Z),F)),equal(Y,Z)). | |
| 248 | simp_rule(member(X,total_function(Dom,Ran)),conjunct(Conj1,Conj2),'DEF_IN_TFCT') :- | |
| 249 | Conj1 = member(X,partial_function(Dom,Ran)), | |
| 250 | Conj2 = equal(domain(X),Dom). | |
| 251 | simp_rule(member(F,partial_injection(S,T)),conjunct(member(F,partial_function(S,T)),member(reverse(F),partial_function(T,S))),'DEF_IN_INJ'). | |
| 252 | simp_rule(member(F,total_injection(S,T)),conjunct(member(F,partial_injection(S,T)),equal(domain(F),S)),'DEF_IN_TINJ'). | |
| 253 | simp_rule(member(F,partial_surjection(S,T)),conjunct(member(F,partial_function(S,T)),equal(range(F),T)),'DEF_IN_SURJ'). | |
| 254 | simp_rule(member(F,total_surjection(S,T)),conjunct(member(F,partial_surjection(S,T)),equal(domain(F),S)),'DEF_IN_TSURJ'). | |
| 255 | simp_rule(member(F,total_bijection(S,T)),conjunct(member(F,total_injection(S,T)),equal(range(F),T)),'DEF_IN_BIJ'). | |
| 256 | simp_rule(C,Res,'DISTRI_DOMSUB_BUNION_L') :- distri_l3(C,Res,domain_subtraction,union,intersection). | |
| 257 | simp_rule(C,Res,'DISTRI_DOMSUB_BINTER_L') :- distri_l3(C,Res,domain_subtraction,intersection,union). | |
| 258 | ||
| 259 | simp_rule(C,Res,Rule) :- distri_r2(C,Res,Rule). | |
| 260 | simp_rule(C,Res,Rule) :- distri_r3(C,Res,Rule). | |
| 261 | simp_rule(C,Res,Rule) :- distri_l2(C,Res,Rule). | |
| 262 | simp_rule(reverse(U),Res,'DISTRI_CONVERSE_BUNION') :- U = union(_,_), distri_reverse(U,Res,union). | |
| 263 | simp_rule(reverse(I),Res,'DISTRI_CONVERSE_BINTER') :- I = intersection(_,_), distri_reverse(I,Res,intersection). | |
| 264 | simp_rule(reverse(S),Res,'DISTRI_CONVERSE_SETMINUS') :- S = set_subtraction(_,_), distri_reverse(S,Res,set_subtraction). | |
| 265 | simp_rule(reverse(R),Res,'DISTRI_CONVERSE_BCOMP') :- R = ring(_,_), distri_reverse_reverse(R,Res,ring). | |
| 266 | simp_rule(reverse(R),Res,'DISTRI_CONVERSE_FCOMP') :- R = composition(_,_), distri_reverse_reverse(R,Res,composition). | |
| 267 | simp_rule(reverse(parallel_product(S,R)),parallel_product(reverse(S),reverse(R)),'DISTRI_CONVERSE_PPROD'). | |
| 268 | simp_rule(reverse(domain_restriction(S,R)),range_restriction(reverse(R),S),'DISTRI_CONVERSE_DOMRES'). | |
| 269 | simp_rule(reverse(domain_subtraction(S,R)),range_subtraction(reverse(R),S),'DISTRI_CONVERSE_DOMSUB'). | |
| 270 | simp_rule(reverse(range_restriction(R,S)),domain_restriction(S,reverse(R)),'DISTRI_CONVERSE_RANRES'). | |
| 271 | simp_rule(reverse(range_subtraction(R,S)),domain_subtraction(S,reverse(R)),'DISTRI_CONVERSE_RANSUB'). | |
| 272 | simp_rule(domain(U),Res,'DISTRI_DOM_BUNION') :- U = union(_,_), distri_union(U,Res,domain). | |
| 273 | simp_rule(range(U),Res,'DISTRI_RAN_BUNION') :- U = union(_,_), distri_union(U,Res,range). | |
| 274 | simp_rule(image(R,U),Res,'DISTRI_RELIMAGE_BUNION_R') :- U = union(_,_), image_union(R,U,Res). | |
| 275 | simp_rule(image(U,S),Res,'DISTRI_RELIMAGE_BUNION_L') :- U = union(_,_), union_image(U,S,Res). | |
| 276 | simp_rule(member(LB,interval(LB,UB)),truth,'lower_bound_in_interval') :- number(LB), number(UB), LB =< UB. % own rule: lower bound in interval | |
| 277 | simp_rule(member(Nr,interval(LB,UB)),truth,'SIMP_IN_UPTO') :- number(LB), number(UB), number(Nr), LB =< Nr, Nr =< UB. % own rule | |
| 278 | simp_rule(member(Nr,interval(LB,UB)),falsity,'SIMP_IN_UPTO') :- number(LB), number(UB), number(Nr), (Nr =< LB ; UB =< Nr). % own rule | |
| 279 | simp_rule(member(E,U),Res,'DEF_IN_BUNION') :- U = union(_,_), member_union(E,U,Res). | |
| 280 | simp_rule(member(E,I),Res,'DEF_IN_BINTER') :- I = intersection(_,_), member_intersection(E,I,Res). | |
| 281 | simp_rule(member(couple(E,F),cartesian_product(S,T)),conjunct(member(E,S),member(F,T)),'DEF_IN_MAPSTO'). | |
| 282 | simp_rule(member(E,pow_subset(S)),subset(E,S),'DEF_IN_POW'). | |
| 283 | simp_rule(member(E,pow1_subset(S)),conjunct(member(E,pow_subset(S)),not_equal(S,empty_set)),'DEF_IN_POW1'). | |
| 284 | simp_rule(S,forall([X],member(X,A),member(X,B)),'DEF_SUBSETEQ') :- S = subset(A,B), new_identifier(S,X). | |
| 285 | simp_rule(member(E,set_subtraction(S,T)),conjunct(member(E,S),negation(member(E,T))),'DEF_IN_SETMINUS'). | |
| 286 | simp_rule(member(E,set_extension(L)),D,'DEF_IN_SETENUM') :- L = [A,B|T], | |
| 287 | or_equal(T,E,disjunct(equal(E,A),equal(E,B)),D). | |
| 288 | simp_rule(M,exists([X],conjunct(member(X,S),member(E,X))),'DEF_IN_KUNION') :- | |
| 289 | M = member(E,general_union(S)), | |
| 290 | new_identifier(M,X). | |
| 291 | simp_rule(member(E,general_intersection(S)),forall([X],member(X,S),member(E,X)),'DEF_IN_KINTER') :- new_identifier(S,X). | |
| 292 | simp_rule(member(E,quantified_union(Ids,P,T)),exists(NewIds,conjunct(P1,member(E,T1))),'DEF_IN_QUNION') :- | |
| 293 | length(Ids,L), | |
| 294 | new_identifiers(E,L,NewIds), | |
| 295 | rewrite_pairwise(Ids,NewIds,conjunct(P,T),conjunct(P1,T1)). | |
| 296 | simp_rule(member(E,quantified_intersection(Ids,P,T)),forall(NewIds,P1,member(E,T1)),'DEF_IN_QINTER') :- | |
| 297 | length(Ids,L), | |
| 298 | new_identifiers(E,L,NewIds), | |
| 299 | rewrite_pairwise(Ids,NewIds,conjunct(P,T),conjunct(P1,T1)). | |
| 300 | simp_rule(member(E,interval(L,R)),conjunct(less_equal(L,E),less_equal(E,R)),'DEF_IN_UPTO'). | |
| 301 | simp_rule(C,Res,'DISTRI_BUNION_BINTER') :- distri(C,Res,union,intersection). | |
| 302 | simp_rule(C,Res,'DISTRI_BINTER_BUNION') :- distri(C,Res,intersection,union). | |
| 303 | simp_rule(C,Res,'DISTRI_BINTER_SETMINUS') :- distri(C,Res,intersection,set_subtraction). | |
| 304 | simp_rule(set_subtraction(X,Y),Res,'DISTRI_SETMINUS_BUNION') :- distri_setminus(X,Y,Res). | |
| 305 | simp_rule(C,Res,'DISTRI_CPROD_BINTER') :- distri(C,Res,cartesian_product,intersection). | |
| 306 | simp_rule(C,Res,'DISTRI_CPROD_BUNION') :- distri(C,Res,cartesian_product,union). | |
| 307 | simp_rule(C,Res,'DISTRI_CPROD_SETMINUS') :- distri(C,Res,cartesian_product,set_subtraction). | |
| 308 | simp_rule(subset(set_subtraction(A,B),S),subset(A,union(B,S)),'DERIV_SUBSETEQ_SETMINUS_L'). | |
| 309 | simp_rule(subset(S,set_subtraction(A,B)),conjunct(subset(S,A),equal(intersection(S,B),empty_set)),'DERIV_SUBSETEQ_SETMINUS_R'). | |
| 310 | simp_rule(partition(S,L),Res,'DEF_PARTITION') :- | |
| 311 | length(L,LL), LL > 1, | |
| 312 | list_to_op(L,U,union), | |
| 313 | Eq = equal(S,U), | |
| 314 | findall(equal(intersection(X,Y),empty_set),(all_pairs(L,Pairs), member([X,Y],Pairs)), Disjoint), | |
| 315 | list_to_op([Eq|Disjoint],Res,conjunct). | |
| 316 | simp_rule(partition(S,[]),equal(S,empty_set),'SIMP_EMPTY_PARTITION'). | |
| 317 | simp_rule(partition(S,[T]),equal(S,T),'SIMP_SINGLE_PARTITION'). | |
| 318 | simp_rule(domain(set_extension(L)),set_extension(Res),'SIMP_DOM_SETENUM') :- | |
| 319 | map_dom(L,Dom), | |
| 320 | without_duplicates(Dom,Res). | |
| 321 | simp_rule(range(set_extension(L)),set_extension(Res),'SIMP_RAN_SETENUM') :- | |
| 322 | map_ran(L,Ran), | |
| 323 | without_duplicates(Ran,Res). | |
| 324 | simp_rule(general_union(pow_subset(S)),S,'SIMP_KUNION_POW'). | |
| 325 | simp_rule(general_union(pow1_subset(S)),S,'SIMP_KUNION_POW1'). | |
| 326 | simp_rule(general_union(set_extension([empty_set])),empty_set,'SIMP_SPECIAL_KUNION'). | |
| 327 | simp_rule(quantified_union([_],falsity,_),empty_set,'SIMP_SPECIAL_QUNION'). | |
| 328 | simp_rule(general_intersection(set_extension([empty_set])),empty_set,'SIMP_SPECIAL_KINTER'). | |
| 329 | simp_rule(general_intersection(pow_subset(S)),S,'SIMP_KINTER_POW'). | |
| 330 | simp_rule(pow_subset(empty_set),set_extension([empty_set]),'SIMP_SPECIAL_POW'). | |
| 331 | simp_rule(pow1_subset(empty_set),empty_set,'SIMP_SPECIAL_POW1'). | |
| 332 | simp_rule(event_b_comprehension_set(Ids,X,member(X,S)),S,'SIMP_COMPSET_IN') :- | |
| 333 | used_identifiers(X,Ids), | |
| 334 | free_identifiers(S,Free), | |
| 335 | list_intersection(Ids,Free,[]). | |
| 336 | simp_rule(event_b_comprehension_set(Ids,X,subset(X,S)),pow_subset(S),'SIMP_COMPSET_SUBSETEQ') :- | |
| 337 | used_identifiers(X,Ids), | |
| 338 | free_identifiers(S,Free), | |
| 339 | list_intersection(Ids,Free,[]). | |
| 340 | simp_rule(event_b_comprehension_set(_,_,falsity),empty_set,'SIMP_SPECIAL_COMPSET_BFALSE'). | |
| 341 | simp_rule(event_b_comprehension_set(Ids,F,Conj),event_b_comprehension_set(Ids0,F1,Conj0),'SIMP_COMPSET_EQUAL') :- | |
| 342 | op_to_list(Conj,ConjList,conjunct), | |
| 343 | select(Eq,ConjList,ConjList0), | |
| 344 | is_equality(Eq,X,E), | |
| 345 | list_to_op(ConjList0,Conj0,conjunct), | |
| 346 | free_identifiers(conjunct(E,Conj0),Free), | |
| 347 | op_to_list(X,CIds,couple), | |
| 348 | list_intersection(CIds,Free,[]), | |
| 349 | list_subset(CIds,Ids), | |
| 350 | list_difference(Ids,CIds,Ids0), | |
| 351 | Ids0 \= [], | |
| 352 | rewrite(X,E,F,F1). | |
| 353 | simp_rule(member(E,event_b_comprehension_set(BIds,X,P)),Q,'SIMP_IN_COMPSET_ONEPOINT') :- | |
| 354 | op_to_list(X,IdsX,couple), | |
| 355 | IdsX = BIds, | |
| 356 | op_to_list(E,IdsE,couple), | |
| 357 | length(IdsX,LengthX), | |
| 358 | length(IdsE,LengthE), | |
| 359 | LengthE =:= LengthX, | |
| 360 | rewrite_pairwise(IdsX,IdsE,P,Q). | |
| 361 | simp_rule(member(F,event_b_comprehension_set(Ids,E,P)),exists(Ids,conjunct(P,equal(E,F))),'SIMP_IN_COMPSET') :- | |
| 362 | free_identifiers(F,FreeInF), | |
| 363 | list_intersection(Ids,FreeInF,[]). | |
| 364 | simp_rule(function(event_b_comprehension_set([X],couple(X,E),_),Y),F,'SIMP_FUNIMAGE_LAMBDA') :- rewrite(X,Y,E,F). | |
| 365 | simp_rule(Hyp,New,Rule) :- | |
| 366 | CompSet = event_b_comprehension_set(Ids,couple(E,F),P), | |
| 367 | NewComp = event_b_comprehension_set(Ids,E,P), | |
| 368 | (Hyp = finite(CompSet), New = finite(NewComp), Rule = 'SIMP_FINITE_LAMBDA' ; | |
| 369 | Hyp = card(CompSet), New = card(NewComp), Rule = 'SIMP_CARD_LAMBDA' ), | |
| 370 | used_identifiers(E,IdsE), | |
| 371 | list_subset(Ids,IdsE), | |
| 372 | used_identifiers(F,IdsF), | |
| 373 | list_intersection(IdsF,Ids,BoundF), | |
| 374 | list_subset(BoundF,IdsE). | |
| 375 | simp_rule(R,S,'SIMP_SPECIAL_OVERL') :- R = overwrite(S,empty_set) ; R = overwrite(empty_set,S). | |
| 376 | simp_rule(domain(reverse(R)),range(R),'SIMP_DOM_CONVERSE'). | |
| 377 | simp_rule(range(reverse(R)),domain(R),'SIMP_RAN_CONVERSE'). | |
| 378 | simp_rule(domain_restriction(empty_set,_),empty_set,'SIMP_SPECIAL_DOMRES_L'). | |
| 379 | simp_rule(domain_restriction(_,empty_set),empty_set,'SIMP_SPECIAL_DOMRES_R'). | |
| 380 | simp_rule(domain_restriction(domain(R),R),R,'SIMP_MULTI_DOMRES_DOM'). | |
| 381 | simp_rule(domain_restriction(range(R),reverse(R)),reverse(R),'SIMP_MULTI_DOMRES_RAN'). | |
| 382 | simp_rule(domain_restriction(S,domain_restriction(T,event_b_identity)),domain_restriction(intersection(S,T),event_b_identity),'SIMP_DOMRES_DOMRES_ID'). | |
| 383 | simp_rule(domain_restriction(S,domain_subtraction(T,event_b_identity)),domain_restriction(set_subtraction(S,T),event_b_identity),'SIMP_DOMRES_DOMSUB_ID'). | |
| 384 | simp_rule(range_restriction(_,empty_set),empty_set,'SIMP_SPECIAL_RANRES_R'). | |
| 385 | simp_rule(range_restriction(empty_set,_),empty_set,'SIMP_SPECIAL_RANRES_L'). | |
| 386 | simp_rule(range_restriction(domain_restriction(S,event_b_identity),T),domain_restriction(intersection(S,T),event_b_identity),'SIMP_RANRES_DOMRES_ID'). | |
| 387 | simp_rule(range_restriction(domain_subtraction(S,event_b_identity),T),domain_restriction(set_subtraction(T,S),event_b_identity),'SIMP_RANRES_DOMSUB_ID'). | |
| 388 | simp_rule(range_restriction(R,range(R)),R,'SIMP_MULTI_RANRES_RAN'). | |
| 389 | simp_rule(range_restriction(reverse(R),domain(R)),reverse(R),'SIMP_MULTI_RANRES_DOM'). | |
| 390 | simp_rule(range_restriction(event_b_identity,S),domain_restriction(S,event_b_identity),'SIMP_RANRES_ID'). | |
| 391 | simp_rule(range_subtraction(event_b_identity,S),domain_subtraction(S,event_b_identity),'SIMP_RANSUB_ID'). | |
| 392 | simp_rule(domain_subtraction(empty_set,R),R,'SIMP_SPECIAL_DOMSUB_L'). | |
| 393 | simp_rule(domain_subtraction(_,empty_set),empty_set,'SIMP_SPECIAL_DOMSUB_R'). | |
| 394 | simp_rule(domain_subtraction(domain(R),R),empty_set,'SIMP_MULTI_DOMSUB_DOM'). | |
| 395 | simp_rule(domain_subtraction(range(R),reverse(R)),empty_set,'SIMP_MULTI_DOMSUB_RAN'). | |
| 396 | simp_rule(domain_subtraction(S,domain_restriction(T,event_b_identity)),domain_restriction(set_subtraction(T,S),event_b_identity),'SIMP_DOMSUB_DOMRES_ID'). | |
| 397 | simp_rule(domain_subtraction(S,domain_subtraction(T,event_b_identity)),domain_subtraction(union(S,T),event_b_identity),'SIMP_DOMSUB_DOMSUB_ID'). | |
| 398 | simp_rule(range_subtraction(R,empty_set),R,'SIMP_SPECIAL_RANSUB_R'). | |
| 399 | simp_rule(range_subtraction(empty_set,_),empty_set,'SIMP_SPECIAL_RANSUB_L'). | |
| 400 | simp_rule(range_subtraction(reverse(R),domain(R)),empty_set,'SIMP_MULTI_RANSUB_DOM'). | |
| 401 | simp_rule(range_subtraction(R,range(R)),empty_set,'SIMP_MULTI_RANSUB_RAN'). | |
| 402 | simp_rule(range_subtraction(domain_restriction(S,event_b_identity),T),domain_restriction(set_subtraction(S,T),event_b_identity),'SIMP_RANSUB_DOMRES_ID'). | |
| 403 | simp_rule(range_subtraction(domain_subtraction(S,event_b_identity),T),domain_subtraction(union(S,T),event_b_identity),'SIMP_RANSUB_DOMSUB_ID'). | |
| 404 | simp_rule(C,R,'SIMP_TYPE_FCOMP_ID') :- C = composition(R,event_b_identity) ; C = composition(event_b_identity,R). | |
| 405 | simp_rule(C,R,'SIMP_TYPE_BCOMP_ID') :- C = ring(R,event_b_identity) ; C = ring(event_b_identity,R). | |
| 406 | simp_rule(direct_product(_,empty_set),empty_set,'SIMP_SPECIAL_DPROD_R'). | |
| 407 | simp_rule(direct_product(empty_set,_),empty_set,'SIMP_SPECIAL_DPROD_L'). | |
| 408 | simp_rule(direct_product(cartesian_product(S,T),cartesian_product(U,V)), | |
| 409 | cartesian_product(intersection(S,U),cartesian_product(T,V)),'SIMP_DPROD_CPROD'). | |
| 410 | simp_rule(PP,empty_set,'SIMP_SPECIAL_PPROD') :- PP = parallel_product(_,empty_set) ; PP = parallel_product(empty_set,_). % SIMP_SPECIAL_PPROD_L / SIMP_SPECIAL_PPROD_R | |
| 411 | simp_rule(parallel_product(cartesian_product(S,T),cartesian_product(U,V)), | |
| 412 | cartesian_product(cartesian_product(S,U),cartesian_product(T,V)),'SIMP_PPROD_CPROD'). | |
| 413 | simp_rule(image(_,empty_set),empty_set,'SIMP_SPECIAL_RELIMAGE_R'). | |
| 414 | simp_rule(image(empty_set,_),empty_set,'SIMP_SPECIAL_RELIMAGE_L'). | |
| 415 | simp_rule(image(R,domain(R)),range(R),'SIMP_MULTI_RELIMAGE_DOM'). | |
| 416 | simp_rule(image(event_b_identity,T),T,'SIMP_RELIMAGE_ID'). | |
| 417 | simp_rule(image(domain_restriction(S,event_b_identity),T),intersection(S,T),'SIMP_RELIMAGE_DOMRES_ID'). | |
| 418 | simp_rule(image(domain_subtraction(S,event_b_identity),T),set_subtraction(T,S),'SIMP_RELIMAGE_DOMSUB_ID'). | |
| 419 | simp_rule(image(reverse(range_subtraction(_,S)),S),empty_set,'SIMP_MULTI_RELIMAGE_CONVERSE_RANSUB'). | |
| 420 | simp_rule(image(reverse(range_restriction(R,S)),S),image(reverse(R),S),'SIMP_MULTI_RELIMAGE_CONVERSE_RANRES'). | |
| 421 | simp_rule(image(reverse(domain_subtraction(S,R)),T), | |
| 422 | set_subtraction(image(reverse(R),T),S),'SIMP_RELIMAGE_CONVERSE_DOMSUB'). | |
| 423 | simp_rule(image(range_subtraction(R,S),T),set_subtraction(image(R,T),S),'DERIV_RELIMAGE_RANSUB'). | |
| 424 | simp_rule(image(range_restriction(R,S),T),intersection(image(R,T),S),'DERIV_RELIMAGE_RANRES'). | |
| 425 | simp_rule(image(domain_subtraction(S,_),S),empty_set,'SIMP_MULTI_RELIMAGE_DOMSUB'). | |
| 426 | simp_rule(image(domain_subtraction(S,R),T),image(R,set_subtraction(T,S)),'DERIV_RELIMAGE_DOMSUB'). | |
| 427 | simp_rule(image(domain_restriction(S,R),T),image(R,intersection(S,T)),'DERIV_RELIMAGE_DOMRES'). | |
| 428 | simp_rule(reverse(empty_set),empty_set,'SIMP_SPECIAL_CONVERSE'). | |
| 429 | simp_rule(reverse(event_b_identity),event_b_identity,'SIMP_CONVERSE_ID'). | |
| 430 | simp_rule(member(couple(E,F),set_subtraction(_,event_b_identity)),falsity,'SIMP_SPECIAL_IN_SETMINUS_ID') :- equal_terms(E,F). | |
| 431 | simp_rule(member(couple(E,F),domain_restriction(S,event_b_identity)),member(E,S),'SIMP_SPECIAL_IN_DOMRES_ID') :- | |
| 432 | equal_terms(E,F). | |
| 433 | simp_rule(member(couple(E,F),set_subtraction(R,domain_restriction(S,event_b_identity))), | |
| 434 | member(couple(E,F),domain_subtraction(S,R)),'SIMP_SPECIAL_IN_SETMINUS_DOMRES_ID') :- equal_terms(E,F). | |
| 435 | simp_rule(reverse(cartesian_product(S,T)),cartesian_product(T,S),'SIMP_CONVERSE_CPROD'). | |
| 436 | simp_rule(reverse(set_extension(L)),set_extension(NewL),'SIMP_CONVERSE_SETENUM') :- convert_map_to(L,NewL). | |
| 437 | simp_rule(reverse(event_b_comprehension_set(Ids,couple(X,Y),P)), | |
| 438 | event_b_comprehension_set(Ids,couple(Y,X),P),'SIMP_CONVERSE_COMPSET'). | |
| 439 | simp_rule(composition(domain_restriction(S,event_b_identity),R),domain_restriction(S,R),'SIMP_FCOMP_ID_L'). | |
| 440 | simp_rule(composition(R,domain_restriction(S,event_b_identity)),range_restriction(R,S),'SIMP_FCOMP_ID_R'). | |
| 441 | simp_rule(R,set_extension([empty_set]),'SIMP_SPECIAL_REL_R') :- simp_relation_empty_range(R). | |
| 442 | simp_rule(R,set_extension([empty_set]),'SIMP_SPECIAL_REL_L') :- simp_relation_empty_domain(R). | |
| 443 | simp_rule(function(event_b_first_projection_v2,couple(E,_)),E,'SIMP_FUNIMAGE_PRJ1'). | |
| 444 | simp_rule(function(event_b_second_projection_v2,couple(_,F)),F,'SIMP_FUNIMAGE_PRJ2'). | |
| 445 | simp_rule(member(couple(E,function(F,E)),F),truth,'SIMP_IN_FUNIMAGE'). | |
| 446 | simp_rule(member(couple(function(reverse(F),E),E),F),truth,'SIMP_IN_FUNIMAGE_CONVERSE_L'). | |
| 447 | simp_rule(member(couple(function(F,E),E),reverse(F)),truth,'SIMP_IN_FUNIMAGE_CONVERSE_R'). | |
| 448 | simp_rule(function(set_extension(L),_),E,'SIMP_MULTI_FUNIMAGE_SETENUM_LL') :- all_map_to(L,E). | |
| 449 | simp_rule(function(set_extension(L),X),Y,'SIMP_MULTI_FUNIMAGE_SETENUM_LR') :- member(couple(Z,Y),L), equal_terms(X,Z). | |
| 450 | simp_rule(function(Over,X),Y,'SIMP_MULTI_FUNIMAGE_OVERL_SETENUM') :- | |
| 451 | Over = overwrite(_,_), | |
| 452 | last_overwrite(Over,set_extension(L)), | |
| 453 | member(couple(Z,Y),L), | |
| 454 | equal_terms(X,Z). | |
| 455 | simp_rule(function(U,X),Y,'SIMP_MULTI_FUNIMAGE_BUNION_SETENUM') :- | |
| 456 | member_of(union,set_extension(L),U), | |
| 457 | member(couple(Z,Y),L), | |
| 458 | equal_terms(X,Z). | |
| 459 | simp_rule(function(cartesian_product(_,set_extension([F])),_),F,'SIMP_FUNIMAGE_CPROD'). | |
| 460 | simp_rule(function(F,function(reverse(F),E)),E,'SIMP_FUNIMAGE_FUNIMAGE_CONVERSE'). | |
| 461 | simp_rule(function(reverse(F),function(F,E)),E,'SIMP_FUNIMAGE_CONVERSE_FUNIMAGE'). | |
| 462 | simp_rule(function(set_extension(L),function(set_extension(L2),E)),E,'SIMP_FUNIMAGE_FUNIMAGE_CONVERSE_SETENUM') :- | |
| 463 | convert_map_to(L,LConverted), | |
| 464 | equal_terms(LConverted,L2). | |
| 465 | simp_rule(domain_restriction(SetE,event_b_identity),set_extension([couple(E,E)]),'DERIV_ID_SING') :- singleton_set(SetE,E). | |
| 466 | simp_rule(domain(empty_set),empty_set,'SIMP_SPECIAL_DOM'). | |
| 467 | simp_rule(range(empty_set),empty_set,'SIMP_SPECIAL_RAN'). | |
| 468 | simp_rule(reverse(reverse(R)),R,'SIMP_CONVERSE_CONVERSE'). | |
| 469 | simp_rule(function(event_b_identity,X),X,'SIMP_FUNIMAGE_ID'). | |
| 470 | simp_rule(member(E,Nat),less_equal(0,E),'DEF_IN_NATURAL') :- is_natural_set(Nat). | |
| 471 | simp_rule(member(E,Nat),less_equal(1,E),'DEF_IN_NATURAL1') :- is_natural1_set(Nat). | |
| 472 | simp_rule(div(E,1),E,'SIMP_SPECIAL_DIV_1'). | |
| 473 | simp_rule(div(0,_),0,'SIMP_SPECIAL_DIV_0'). | |
| 474 | simp_rule(power_of(E,1),E,'SIMP_SPECIAL_EXPN_1_R'). | |
| 475 | simp_rule(power_of(1,_),1,'SIMP_SPECIAL_EXPN_1_L'). | |
| 476 | simp_rule(power_of(_,0),1,'SIMP_SPECIAL_EXPN_0'). | |
| 477 | simp_rule(A,S,'SIMP_SPECIAL_PLUS') :- A = add(S,0) ; A = add(0,S). | |
| 478 | simp_rule(multiplication(A,B),Res,Rule) :- | |
| 479 | op_to_list(multiplication(A,B),L,multiplication), | |
| 480 | change_sign(L,NL,Nr), | |
| 481 | list_to_op(NL,New,multiplication), | |
| 482 | (Nr mod 2 =:= 0 -> Rule = 'SIMP_SPECIAL_PROD_MINUS_EVEN', Res = New | |
| 483 | ; Rule = 'SIMP_SPECIAL_PROD_MINUS_ODD', Res = unary_minus(New)). | |
| 484 | simp_rule(unary_minus(I),J,'SIMP_LIT_MINUS') :- number(I), J is I * (-1). | |
| 485 | simp_rule(minus(E,0),E,'SIMP_SPECIAL_MINUS_R'). | |
| 486 | simp_rule(minus(0,E),unary_minus(E),'SIMP_SPECIAL_MINUS_L'). | |
| 487 | simp_rule(unary_minus(F),E,'SIMP_MINUS_MINUS') :- is_minus(F,E). | |
| 488 | simp_rule(minus(E,F),add(E,F2),'SIMP_MINUS_UNMINUS') :- is_minus(F,F2). | |
| 489 | simp_rule(minus(E,F),0,'SIMP_MULTI_MINUS') :- equal_terms(E,F). | |
| 490 | simp_rule(minus(S,C),S0,'SIMP_MULTI_MINUS_PLUS_L') :- select_op(C,S,S0,add). | |
| 491 | simp_rule(minus(C,S),unary_minus(S0),'SIMP_MULTI_MINUS_PLUS_R') :- select_op(C,S,S0,add). | |
| 492 | simp_rule(minus(S1,S2),minus(S01,S02),'SIMP_MULTI_MINUS_PLUS_PLUS') :- | |
| 493 | member_of(add,El,S1), | |
| 494 | select_op(El,S1,S01,add), | |
| 495 | select_op(El,S2,S02,add), | |
| 496 | S01 = add(_,_), | |
| 497 | S02 = add(_,_). | |
| 498 | simp_rule(S,S1,'SIMP_MULTI_PLUS_MINUS') :- | |
| 499 | member_of(add,minus(C,D),S), | |
| 500 | select_op(D,S,S0,add), | |
| 501 | select_op(minus(C,D),S0,C,S1,add). | |
| 502 | simp_rule(Ex,Res,Rule) :- simp_multi_arithrel(Ex,Res,Rule). | |
| 503 | simp_rule(Ex,Res,'SIMP_MULTI_ARITHREL') :- % own rule for cases not covered by SIMP_MULTI_ARITHREL_[...] | |
| 504 | \+ simp_multi_arithrel(Ex,Res,_), | |
| 505 | Ex=..[Rel,L,R], | |
| 506 | comparison(Rel), | |
| 507 | (select_summand(L,Term,L0), | |
| 508 | select_summand(R,Term,R0) | |
| 509 | ; select_subtrahend(L,Term,L0), | |
| 510 | select_subtrahend(R,Term,R0) ), | |
| 511 | NewEx=..[Rel,L0,R0], | |
| 512 | normalize_minus(NewEx,Res). | |
| 513 | simp_rule(P,E,'SIMP_SPECIAL_PROD_1') :- P = multiplication(E,1) ; P = multiplication(1,E). | |
| 514 | simp_rule(min(set_extension(L)),min(set_extension(Res)),'SIMP_LIT_MIN') :- | |
| 515 | min_list(L,I), | |
| 516 | remove_greater(L,I,Res). | |
| 517 | simp_rule(max(set_extension(L)),max(set_extension(Res)),'SIMP_LIT_MAX') :- | |
| 518 | max_list(L,I), | |
| 519 | remove_smaller(L,I,Res). | |
| 520 | simp_rule(card(empty_set),0,'SIMP_SPECIAL_CARD'). | |
| 521 | simp_rule(card(set_extension([_])),1,'SIMP_CARD_SING'). | |
| 522 | simp_rule(card(pow_subset(S)),power_of(2,card(S)),'SIMP_CARD_POW'). | |
| 523 | simp_rule(card(union(S,T)),minus(add(card(S),card(T)),card(intersection(S,T))),'SIMP_CARD_BUNION'). | |
| 524 | simp_rule(card(reverse(R)),card(R),'SIMP_CARD_CONVERSE'). | |
| 525 | simp_rule(card(domain_restriction(S,event_b_identity)),S,'SIMP_CARD_ID_DOMRES'). | |
| 526 | simp_rule(card(domain_restriction(E,event_b_first_projection_v2)),E,'SIMP_CARD_PRJ1_DOMRES'). | |
| 527 | simp_rule(card(domain_restriction(E,event_b_second_projection_v2)),E,'SIMP_CARD_PRJ2_DOMRES'). | |
| 528 | simp_rule(P,falsity,'SIMP_MULTI_LT') :- is_less(P,E,F), equal_terms(E,F). % covers SIMP_MULTI_GT too | |
| 529 | simp_rule(div(NE,NF),div(E,F),'SIMP_DIV_MINUS') :- is_minus(NE,E), is_minus(NF,F). | |
| 530 | simp_rule(div(E,F),1,'SIMP_MULTI_DIV') :- equal_terms(E,F). | |
| 531 | simp_rule(modulo(0,_),0,'SIMP_SPECIAL_MOD_0'). | |
| 532 | simp_rule(modulo(_,1),0,'SIMP_SPECIAL_MOD_1'). | |
| 533 | simp_rule(modulo(E,F),1,'SIMP_MULTI_MOD') :- equal_terms(E,F). | |
| 534 | simp_rule(min(SetE),E,'SIMP_MIN_SING') :- singleton_set(SetE,E). | |
| 535 | simp_rule(max(SetE),E,'SIMP_MAX_SING') :- singleton_set(SetE,E). | |
| 536 | simp_rule(div(P1,E2),P0,'SIMP_MULTI_DIV_PROD') :- | |
| 537 | member_of(multiplication,E1,P1), | |
| 538 | equal_terms(E1,E2), | |
| 539 | select_op(E1,P1,P0,multiplication). | |
| 540 | simp_rule(card(set_extension(L)),LL,'SIMP_TYPE_CARD') :- length(L,LL). | |
| 541 | simp_rule(card(interval(I,J)),Res,'SIMP_LIT_CARD_UPTO') :- number(I), number(J), I =< J, Res is J - I + 1. | |
| 542 | simp_rule(card(interval(I,J)),0,'SIMP_LIT_CARD_UPTO') :- number(I), number(J), I > J. % from "Proposal for an extensible rule-based prover for Event-B", pg. 7 | |
| 543 | simp_rule(P,negation(equal(S,empty_set)),'SIMP_LIT_LE_CARD_1') :- is_less_eq(P,1,card(S)). | |
| 544 | simp_rule(P,negation(equal(S,empty_set)),'SIMP_LIT_LT_CARD_0') :- is_less(P,0,card(S)). | |
| 545 | simp_rule(member(card(S),Nat),negation(equal(S,empty_set)),'SIMP_CARD_NATURAL1') :- is_natural1_set(Nat). | |
| 546 | simp_rule(equal(card(S),card(T)),exists([F],member(F,total_bijection(S,T))),'SIMP_EQUAL_CARD') :- | |
| 547 | new_function(conjunct(S,T),F). | |
| 548 | simp_rule(member(0,Nat),falsity,'SIMP_SPECIAL_IN_NATURAL1') :- is_natural1_set(Nat). | |
| 549 | simp_rule(interval(I,J),empty_set,'SIMP_LIT_UPTO') :- number(I), number(J), I > J. | |
| 550 | simp_rule(member(NI,Nat),falsity,'SIMP_LIT_IN_MINUS_NATURAL') :- | |
| 551 | is_natural_set(Nat), | |
| 552 | (NI = unary_minus(I), number(I), I > 0 | |
| 553 | ; number(NI), NI < 0). | |
| 554 | simp_rule(member(NI,Nat),falsity,'SIMP_LIT_IN_MINUS_NATURAL1') :- | |
| 555 | is_natural1_set(Nat), | |
| 556 | (NI = unary_minus(I), number(I), I >= 0 | |
| 557 | ; number(NI), NI < 0). | |
| 558 | simp_rule(min(Nat),0,'SIMP_MIN_NATURAL') :- is_natural_set(Nat). | |
| 559 | simp_rule(min(Nat),1,'SIMP_MIN_NATURAL1') :- is_natural1_set(Nat). | |
| 560 | simp_rule(max(interval(_,F)),F,'SIMP_MAX_UPTO'). | |
| 561 | simp_rule(min(interval(E,_)),E,'SIMP_MIN_UPTO'). | |
| 562 | simp_rule(min(U),min(New),'SIMP_MIN_BUNION_SING') :- U = union(_,_), select_op(set_extension([min(T)]),U,T,New,union). | |
| 563 | simp_rule(max(U),max(New),'SIMP_MAX_BUNION_SING') :- U = union(_,_), select_op(set_extension([max(T)]),U,T,New,union). | |
| 564 | simp_rule(negation(P),Q,Rule) :- seperate_negate_rule(Rule,P), negate(P,Q). | |
| 565 | simp_rule(negation(P),Q,'Propagate negation') :- | |
| 566 | \+ seperate_negate_rule(_,P), | |
| 567 | negate(P,Q), | |
| 568 | Q \= negation(_). % De-Morgan and similar rules to propagate negation | |
| 569 | simp_rule(P,truth,'Evaluate tautology') :- is_true(P). | |
| 570 | simp_rule(E,NewE,Rule) :- is_empty(E,EmptyTerm), simp_empty_rule(EmptyTerm,NewE,Rule). | |
| 571 | simp_rule(E,NewE,Rule) :- is_equality(E,LHS,RHS), simp_equality(LHS,RHS,NewE,Rule). | |
| 572 | ||
| 573 | new_function(Expr,F) :- used_identifiers(Expr,L), possible_function(X), F = '$'(X), \+ member(F,L), !. | |
| 574 | ||
| 575 | func_id(f). | |
| 576 | func_id(g). | |
| 577 | func_id(h). | |
| 578 | ||
| 579 | possible_function(Z) :- func_id(Z). | |
| 580 | possible_function(Z) :- func_id(X), func_id(Y), atom_concat(X,Y,Z). | |
| 581 | ||
| 582 | seperate_negate_rule('SIMP_NOT_NOT',negation(_)). | |
| 583 | seperate_negate_rule('DISTRI_NOT_AND',conjunct(_,_)). | |
| 584 | seperate_negate_rule('DISTRI_NOT_OR',disjunct(_,_)). | |
| 585 | seperate_negate_rule('DERIV_NOT_IMP',implication(_,_)). | |
| 586 | ||
| 587 | ||
| 588 | overwrite_type([Ty|R],_,ListOut,Info) :- type_expression(Ty,Info), !, overwrite_type(R,[Ty],ListOut,Info). | |
| 589 | overwrite_type([S|R],Prev,ListOut,Info) :- append(Prev,[S],ListIn), overwrite_type(R,ListIn,ListOut,Info). | |
| 590 | overwrite_type([],L,L,_). | |
| 591 | ||
| 592 | change_sign(L,NL,Nr) :- remove_minus(L,NL,Nr), Nr > 0. | |
| 593 | ||
| 594 | remove_minus([NE|R],[E|T],NrN) :- is_minus(NE,E), remove_minus(R,T,Nr), NrN is Nr + 1, !. | |
| 595 | remove_minus([E|R],[E|T],Nr) :- remove_minus(R,T,Nr). | |
| 596 | remove_minus([],[],0). | |
| 597 | ||
| 598 | remove_unused_identifier(L,P,Used) :- | |
| 599 | member(Z,L), | |
| 600 | used_identifiers(P,Ids), | |
| 601 | member(Z,Ids), | |
| 602 | list_intersection(L,Ids,Used). | |
| 603 | ||
| 604 | ||
| 605 | min_list([H|T], Min) :- number(H) -> min_list(T,H,Min) ; min_list(T,Min). | |
| 606 | ||
| 607 | min_list([],Min,Min). | |
| 608 | min_list([H|T],Min0,Min) :- | |
| 609 | number(H),!, | |
| 610 | Min1 is min(H,Min0), | |
| 611 | min_list(T,Min1,Min). | |
| 612 | min_list([_|T],Min0,Min) :- | |
| 613 | min_list(T,Min0,Min). | |
| 614 | ||
| 615 | remove_greater(L,I,Res) :- only_min(L,I,[],Res). | |
| 616 | ||
| 617 | only_min([],_,List,List). | |
| 618 | only_min([E|R],I,Filtered, Res) :- | |
| 619 | \+ number(E),!, | |
| 620 | append(Filtered,[E],New), | |
| 621 | only_min(R,I,New,Res). | |
| 622 | only_min([E|R],I,Filtered,Res) :- | |
| 623 | E > I, | |
| 624 | only_min(R,I,Filtered,Res). | |
| 625 | only_min([E|R],I,Filtered,Res) :- | |
| 626 | E =:= I, | |
| 627 | member(E,Filtered), | |
| 628 | only_min(R,I,Filtered,Res). | |
| 629 | only_min([E|R],I,Filtered,Res) :- | |
| 630 | E =:= I, | |
| 631 | \+ member(E,Filtered), | |
| 632 | append(Filtered,[E],New), | |
| 633 | only_min(R,I,New,Res). | |
| 634 | ||
| 635 | max_list([H|T],Max) :- number(H) -> max_list(T,H,Max) ; max_list(T,Max). | |
| 636 | ||
| 637 | max_list([],Max,Max). | |
| 638 | max_list([H|T],Max0,Max) :- | |
| 639 | number(H),!, | |
| 640 | Max1 is max(H,Max0), | |
| 641 | max_list(T,Max1,Max). | |
| 642 | max_list([_|T],Max0,Max) :- | |
| 643 | max_list(T,Max0,Max). | |
| 644 | ||
| 645 | remove_smaller(L,I,Res) :- only_max(L,I,[],Res). | |
| 646 | ||
| 647 | only_max([],_,List,List). | |
| 648 | only_max([E|R],I,Filtered, Res) :- | |
| 649 | \+ number(E),!, | |
| 650 | append(Filtered,[E],New), | |
| 651 | only_max(R,I,New,Res). | |
| 652 | only_max([E|R],I,Filtered,Res) :- | |
| 653 | E < I, | |
| 654 | only_max(R,I,Filtered,Res). | |
| 655 | only_max([E|R],I,Filtered,Res) :- | |
| 656 | E =:= I, | |
| 657 | member(E,Filtered), | |
| 658 | only_max(R,I,Filtered,Res). | |
| 659 | only_max([E|R],I,Filtered,Res) :- | |
| 660 | E =:= I, | |
| 661 | \+ member(E,Filtered), | |
| 662 | append(Filtered,[E],New), | |
| 663 | only_max(R,I,New,Res). | |
| 664 | ||
| 665 | % ----------------- | |
| 666 | ||
| 667 | ||
| 668 | % simplification rules for equality | |
| 669 | % simp_equality(LHS,RHS,NewPred,'RuleName'). | |
| 670 | simp_equality(interval(_,_),Z,falsity,Rule) :- | |
| 671 | ( is_integer_set(Z) -> Rule = 'SIMP_UPTO_EQUAL_INTEGER' | |
| 672 | ; is_natural_set(Z) -> Rule = 'SIMP_UPTO_EQUAL_NATURAL' | |
| 673 | ; is_natural1_set(Z) -> Rule = 'SIMP_UPTO_EQUAL_NATURAL1'). | |
| 674 | simp_equality(convert_bool(P),boolean_true,P,'SIMP_LIT_EQUAL_KBOOL_TRUE'). | |
| 675 | simp_equality(convert_bool(P),boolean_false,negation(P),'SIMP_LIT_EQUAL_KBOOL_FALSE'). | |
| 676 | simp_equality(T,U,subset(NewU,T),'SIMP_MULTI_EQUAL_BUNION') :- | |
| 677 | member_of(union,T,U), | |
| 678 | remove_from_op(T,U,NewU,union). | |
| 679 | simp_equality(I,T,subset(T,NewI),'SIMP_MULTI_EQUAL_BINTER') :- | |
| 680 | member_of(intersection,T,I), | |
| 681 | remove_from_op(T,I,NewI,intersection). | |
| 682 | simp_equality(function(F,X),Y,member(couple(X,Y),F),'DEF_EQUAL_FUNIMAGE'). | |
| 683 | simp_equality(card(S),0,equal(S,empty_set),'SIMP_SPECIAL_EQUAL_CARD'). | |
| 684 | simp_equality(card(S),1,exists([X],equal(S,set_extension([X]))),'SIMP_LIT_EQUAL_CARD_1') :- | |
| 685 | new_identifier(S,X). | |
| 686 | simp_equality(card(S),K,member(F,total_bijection(interval(1,K),S)),'DEF_EQUAL_CARD') :- | |
| 687 | new_function(conjunct(S,K),F). | |
| 688 | simp_equality(E,min(S),conjunct(member(E,S),forall([X],member(X,S),less_equal(E,X))),'DEF_EQUAL_MIN') :- | |
| 689 | new_identifier(member(E,S),X). | |
| 690 | simp_equality(E,max(S),conjunct(member(E,S),forall([X],member(X,S),greater_equal(E,X))),'DEF_EQUAL_MAX') :- | |
| 691 | new_identifier(member(E,S),X). | |
| 692 | ||
| 693 | ||
| 694 | % candidates for SIMP_SPECIAL_REL_R rule rewriting to {{}} | |
| 695 | simp_relation_empty_range(relations(_,empty_set)). | |
| 696 | simp_relation_empty_range(surjection_relation(_,empty_set)). | |
| 697 | simp_relation_empty_range(partial_function(_,empty_set)). | |
| 698 | simp_relation_empty_range(partial_injection(_,empty_set)). | |
| 699 | simp_relation_empty_range(partial_surjection(_,empty_set)). | |
| 700 | ||
| 701 | % candidates for SIMP_SPECIAL_REL_L rule rewriting to {{}} | |
| 702 | simp_relation_empty_domain(relations(empty_set,_)). | |
| 703 | simp_relation_empty_domain(total_relation(empty_set,_)). | |
| 704 | simp_relation_empty_domain(partial_function(empty_set,_)). | |
| 705 | simp_relation_empty_domain(total_function(empty_set,_)). | |
| 706 | simp_relation_empty_domain(partial_injection(empty_set,_)). | |
| 707 | simp_relation_empty_domain(total_injection(empty_set,_)). | |
| 708 | ||
| 709 | % simplification rules for empty set equalities | |
| 710 | % simp_empty_rule(TermThatIsEmpty,NewPredicate,RuleName) | |
| 711 | simp_empty_rule(set_extension(L),Res,'SIMP_SETENUM_EQUAL_EMPTY') :- length(L,LL), | |
| 712 | (LL > 0 -> Res = falsity ; Res = truth). | |
| 713 | simp_empty_rule(interval(I,J),greater(I,J),'SIMP_UPTO_EQUAL_EMPTY'). | |
| 714 | simp_empty_rule(relations(_,_),falsity,'SIMP_SPECIAL_EQUAL_REL'). | |
| 715 | simp_empty_rule(total_relation(A,B),conjunct(negation(equal(A,empty_set)),equal(B,empty_set)),'SIMP_SPECIAL_EQUAL_RELDOM'). | |
| 716 | simp_empty_rule(total_function(A,B),conjunct(negation(equal(A,empty_set)),equal(B,empty_set)),'SIMP_SPECIAL_EQUAL_RELDOM'). | |
| 717 | simp_empty_rule(surjection_relation(A,B),conjunct(equal(A,empty_set),negation(equal(B,empty_set))), | |
| 718 | 'SIMP_SREL_EQUAL_EMPTY'). | |
| 719 | simp_empty_rule(total_surjection_relation(A,B),equivalence(equal(A,empty_set),negation(equal(B,empty_set))), | |
| 720 | 'SIMP_STREL_EQUAL_EMPTY'). | |
| 721 | simp_empty_rule(domain(R),equal(R,empty_set),'SIMP_DOM_EQUAL_EMPTY'). | |
| 722 | simp_empty_rule(range(R),equal(R,empty_set),'SIMP_RAN_EQUAL_EMPTY'). | |
| 723 | simp_empty_rule(composition(P,Q),equal(intersection(range(P),domain(Q)),empty_set),'SIMP_FCOMP_EQUAL_EMPTY'). | |
| 724 | simp_empty_rule(ring(P,Q),equal(intersection(range(Q),domain(P)),empty_set),'SIMP_BCOMP_EQUAL_EMPTY'). | |
| 725 | simp_empty_rule(domain_restriction(S,R),equal(intersection(domain(R),S),empty_set),'SIMP_DOMRES_EQUAL_EMPTY'). | |
| 726 | simp_empty_rule(domain_subtraction(S,R),subset(domain(R),S),'SIMP_DOMSUB_EQUAL_EMPTY'). | |
| 727 | simp_empty_rule(range_restriction(R,S),equal(intersection(range(R),S),empty_set),'SIMP_RANRES_EQUAL_EMPTY'). | |
| 728 | simp_empty_rule(range_subtraction(R,S),subset(range(R),S),'SIMP_RANSUB_EQUAL_EMPTY'). | |
| 729 | simp_empty_rule(reverse(R),equal(R,empty_set),'SIMP_CONVERSE_EQUAL_EMPTY'). | |
| 730 | simp_empty_rule(image(R,S),equal(domain_restriction(S,R),empty_set),'SIMP_RELIMAGE_EQUAL_EMPTY'). | |
| 731 | simp_empty_rule(overwrite(P,Q),Res,'SIMP_OVERL_EQUAL_EMPTY') :- | |
| 732 | and_empty(overwrite(P,Q),Res,overwrite). | |
| 733 | simp_empty_rule(direct_product(P,Q),equal(intersection(domain(P),domain(Q)),empty_set),'SIMP_DPROD_EQUAL_EMPTY'). | |
| 734 | simp_empty_rule(parallel_product(P,Q),disjunct(equal(P,empty_set),equal(Q,empty_set)),'SIMP_PPROD_EQUAL_EMPTY'). | |
| 735 | simp_empty_rule(event_b_identity,falsity,'SIMP_ID_EQUAL_EMPTY'). | |
| 736 | simp_empty_rule(event_b_first_projection_v2,falsity,'SIMP_PRJ1_EQUAL_EMPTY'). | |
| 737 | simp_empty_rule(event_b_second_projection_v2,falsity,'SIMP_PRJ2_EQUAL_EMPTY'). | |
| 738 | simp_empty_rule(cartesian_product(S,T),disjunct(equal(S,empty_set),equal(T,empty_set)),'SIMP_CPROD_EQUAL_EMPTY'). | |
| 739 | simp_empty_rule(quantified_union([X],P,E),forall([X],P,equal(E,empty_set)),'SIMP_QUNION_EQUAL_EMPTY'). | |
| 740 | simp_empty_rule(union(A,B),Res,'SIMP_BUNION_EQUAL_EMPTY') :- and_empty(union(A,B),Res,union). | |
| 741 | simp_empty_rule(set_subtraction(A,B),subset(A,B),'SIMP_SETMINUS_EQUAL_EMPTY'). | |
| 742 | simp_empty_rule(event_b_comprehension_set(Ids,_,P),forall(Ids,truth,negation(P)),'SIMP_SPECIAL_EQUAL_COMPSET'). | |
| 743 | simp_empty_rule(pow_subset(_),falsity,'SIMP_POW_EQUAL_EMPTY'). | |
| 744 | simp_empty_rule(pow1_subset(S),equal(S,empty_set),'SIMP_POW1_EQUAL_EMPTY'). % TODO: similar rules for FIN/FIN1 ? | |
| 745 | simp_empty_rule(general_union(S),subset(S,set_extension([empty_set])),'SIMP_KUNION_EQUAL_EMPTY'). | |
| 746 | simp_empty_rule(I,equal(set_subtraction(I0,C),empty_set),'SIMP_BINTER_SETMINUS_EQUAL_EMPTY') :- | |
| 747 | member_of(intersection,set_subtraction(B,C),I), | |
| 748 | select_op(minus(B,C),I,B,I0,intersection). | |
| 749 | simp_empty_rule(Nat,falsity,'SIMP_NATURAL_EQUAL_EMPTY') :- is_natural_set(Nat). | |
| 750 | simp_empty_rule(Nat,falsity,'SIMP_NATURAL1_EQUAL_EMPTY') :- is_natural1_set(Nat). | |
| 751 | %simp_empty_rule(TermThatIsEmpty,NewPred,RuleName). | |
| 752 | ||
| 753 | simp_multi_arithrel(Ex,Res,'SIMP_MULTI_ARITHREL_PLUS_PLUS') :- | |
| 754 | Ex=..[Rel,L,R], | |
| 755 | comparison(Rel), | |
| 756 | R = add(_,_), | |
| 757 | member_of(add,El,L), | |
| 758 | select_op(El,L,L0,add), | |
| 759 | select_op(El,R,R0,add), | |
| 760 | Res=..[Rel,L0,R0]. | |
| 761 | simp_multi_arithrel(Ex,Res,'SIMP_MULTI_ARITHREL_PLUS_R') :- | |
| 762 | Ex=..[Rel,C,R], | |
| 763 | comparison(Rel), | |
| 764 | R = add(_,_), | |
| 765 | select_op(C,R,R0,add), | |
| 766 | Res=..[Rel,0,R0]. | |
| 767 | simp_multi_arithrel(Ex,Res,'SIMP_MULTI_ARITHREL_PLUS_L') :- | |
| 768 | Ex=..[Rel,L,C], | |
| 769 | comparison(Rel), | |
| 770 | L = add(_,_), | |
| 771 | select_op(C,L,L0,add), | |
| 772 | Res=..[Rel,L0,0]. | |
| 773 | simp_multi_arithrel(Ex,Res,'SIMP_MULTI_ARITHREL_MINUS_MINUS_R') :- | |
| 774 | Ex=..[Rel,L,R], | |
| 775 | comparison(Rel), | |
| 776 | L = minus(A,C1), | |
| 777 | R = minus(B,C2), | |
| 778 | equal_terms(C1,C2), | |
| 779 | Res=..[Rel,A,B]. | |
| 780 | simp_multi_arithrel(Ex,Res,'SIMP_MULTI_ARITHREL_MINUS_MINUS_L') :- | |
| 781 | Ex=..[Rel,L,R], | |
| 782 | comparison(Rel), | |
| 783 | L = minus(C1,A), | |
| 784 | R = minus(C2,B), | |
| 785 | equal_terms(C1,C2), | |
| 786 | Res=..[Rel,B,A]. | |
| 787 | ||
| 788 | select_summand(X,Y,0) :- equal_terms(X,Y). | |
| 789 | select_summand(add(L,R),X,ResTerm) :- select_summand(L,X,NewL), if_zero(NewL,R,add(NewL,R),ResTerm). | |
| 790 | select_summand(add(L,R),X,ResTerm) :- select_summand(R,X,NewR), if_zero(NewR,L,add(L,NewR),ResTerm). | |
| 791 | select_summand(minus(L,R),X,ResTerm) :- select_summand(L,X,NewL), if_zero(NewL,unary_minus(R),minus(NewL,R),ResTerm). | |
| 792 | ||
| 793 | select_subtrahend(MinusY,X,0) :- is_minus(MinusY,Y), equal_terms(X,Y). | |
| 794 | select_subtrahend(minus(Y,X),X,Y). | |
| 795 | select_subtrahend(add(MinusX,Y),X,Res) :- select_subtrahend(MinusX,X,NewR), if_zero(NewR,Y,add(NewR,Y),Res). | |
| 796 | select_subtrahend(add(Y,MinusX),X,Res) :- select_subtrahend(MinusX,X,NewR), if_zero(NewR,Y,add(Y,NewR),Res). | |
| 797 | select_subtrahend(minus(L,Y),X,Res) :- select_subtrahend(L,X,NewL), if_zero(NewL,unary_minus(Y),minus(NewL,Y),Res). | |
| 798 | ||
| 799 | if_zero(Term,Then,Else,Res) :- | |
| 800 | (Term = 0 | |
| 801 | -> Res = Then | |
| 802 | ; Res = Else). | |
| 803 | ||
| 804 | ||
| 805 | all_pairs(L,Pairs) :- findall([X,Y], (combination(L,[X,Y])), Pairs). | |
| 806 | ||
| 807 | combination(_,[]). | |
| 808 | combination([X|T],[X|C]) :- combination(T,C). | |
| 809 | combination([_|T],[X|C]) :- combination(T,[X|C]). | |
| 810 | ||
| 811 | ||
| 812 | all_in_set([E],S,Hyps) :- member_hyps(member(E,S),Hyps). | |
| 813 | all_in_set([E|R],S,Hyps) :- member_hyps(member(E,S),Hyps), all_in_set(R,S,Hyps). | |
| 814 | ||
| 815 | map_dom([couple(X,_)],[X]) :- !. | |
| 816 | map_dom([couple(X,_)|T],[X|R]) :- map_dom(T,R). | |
| 817 | ||
| 818 | map_ran([couple(_,A)],[A]) :- !. | |
| 819 | map_ran([couple(_,B)|T],[B|R]) :- map_ran(T,R). | |
| 820 | ||
| 821 | all_map_to([couple(_,F)],E) :- equal_terms(E,F), !. | |
| 822 | all_map_to([couple(_,F)|T],E) :- equal_terms(E,F), all_map_to(T,E). | |
| 823 | ||
| 824 | convert_map_to([couple(X,Y)],[couple(Y,X)]) :- !. | |
| 825 | convert_map_to([couple(X,Y)|T],[couple(Y,X)|R]) :- convert_map_to(T,R). | |
| 826 | ||
| 827 | list_subset([],_). | |
| 828 | list_subset([E|T],L) :- memberchk(E,L), list_subset(T,L). | |
| 829 | ||
| 830 | ||
| 831 | ||
| 832 | % ----------------- | |
| 833 | ||
| 834 | ||
| 835 | distri(C,Res,Op1,Op2) :- | |
| 836 | C=..[Op1,A,B], | |
| 837 | (X = A ; X = B), | |
| 838 | functor(X,Op2,2), | |
| 839 | distribute_op(C,X,Op1,Op2,Res). | |
| 840 | ||
| 841 | distri_r2(C,Res,Rule) :- | |
| 842 | C=..[Op1,_,X], | |
| 843 | functor(X,Op2,2), | |
| 844 | distri_r2_name(Op1,Op2,Rule), | |
| 845 | distribute_op(C,X,Op1,Op2,Res). | |
| 846 | distri_r2_name(ring,union,'DISTRI_BCOMP_BUNION'). | |
| 847 | distri_r2_name(direct_product,union,'DISTRI_DPROD_BUNION'). | |
| 848 | distri_r2_name(direct_product,set_subtraction,'DISTRI_DPROD_SETMINUS'). | |
| 849 | distri_r2_name(direct_product,intersection,'DISTRI_DPROD_BINTER'). | |
| 850 | distri_r2_name(direct_product,overwrite,'DISTRI_DPROD_OVERL'). | |
| 851 | distri_r2_name(parallel_product,union,'DISTRI_PPROD_BUNION'). | |
| 852 | distri_r2_name(parallel_product,intersection,'DISTRI_PPROD_BINTER'). | |
| 853 | distri_r2_name(parallel_product,set_subtraction,'DISTRI_PPROD_SETMINUS'). | |
| 854 | distri_r2_name(parallel_product,overwrite,'DISTRI_PPROD_OVERL'). | |
| 855 | distri_r2_name(domain_restriction,union,'DISTRI_DOMRES_BUNION_R'). | |
| 856 | distri_r2_name(domain_restriction,intersection,'DISTRI_DOMRES_BINTER_R'). | |
| 857 | distri_r2_name(domain_restriction,set_subtraction,'DISTRI_DOMRES_SETMINUS_R'). | |
| 858 | distri_r2_name(domain_restriction,direct_product,'DISTRI_DOMRES_DPROD'). | |
| 859 | distri_r2_name(domain_restriction,overwrite,'DISTRI_DOMRES_OVERL'). | |
| 860 | distri_r2_name(domain_subtraction,union,'DISTRI_DOMSUB_BUNION_R'). | |
| 861 | distri_r2_name(domain_subtraction,intersection,'DISTRI_DOMSUB_BINTER_R'). | |
| 862 | distri_r2_name(domain_subtraction,direct_product,'DISTRI_DOMSUB_DPROD'). | |
| 863 | distri_r2_name(domain_subtraction,overwrite,'DISTRI_DOMSUB_OVERL'). | |
| 864 | distri_r2_name(composition,union,'DISTRI_FCOMP_BUNION_R'). | |
| 865 | distri_r2_name(range_restriction,union,'DISTRI_RANRES_BUNION_R'). | |
| 866 | distri_r2_name(range_restriction,intersection,'DISTRI_RANRES_BINTER_R'). | |
| 867 | distri_r2_name(range_restriction,set_subtraction,'DISTRI_RANRES_SETMINUS_R'). | |
| 868 | ||
| 869 | distri_l2(C,Res,RuleName) :- | |
| 870 | distri_l2_arg1(C,Op1,X), | |
| 871 | functor(X,Op2,2), | |
| 872 | distri_l2_name(Op1,Op2,RuleName), | |
| 873 | distribute_op(C,X,Op1,Op2,Res). | |
| 874 | distri_l2_arg1(overwrite(X,_),overwrite,X). | |
| 875 | distri_l2_arg1(composition(X,_),composition,X). | |
| 876 | distri_l2_arg1(domain_restriction(X,_),domain_restriction,X). | |
| 877 | distri_l2_arg1(range_restriction(X,_),range_restriction,X). | |
| 878 | distri_l2_arg1(range_subtraction(X,_),range_subtraction,X). | |
| 879 | distri_l2_name(overwrite,union,'DISTRI_OVERL_BUNION_L'). | |
| 880 | distri_l2_name(overwrite,intersection,'DISTRI_OVERL_BINTER_L'). | |
| 881 | distri_l2_name(composition,union,'DISTRI_FCOMP_BUNION_L'). | |
| 882 | distri_l2_name(domain_restriction,union,'DISTRI_DOMRES_BUNION_L'). | |
| 883 | distri_l2_name(domain_restriction,intersection,'DISTRI_DOMRES_BINTER_L'). | |
| 884 | distri_l2_name(domain_restriction,set_subtraction,'DISTRI_DOMRES_SETMINUS_L'). | |
| 885 | distri_l2_name(range_restriction,union,'DISTRI_RANRES_BUNION_L'). | |
| 886 | distri_l2_name(range_restriction,intersection,'DISTRI_RANRES_BINTER_L'). | |
| 887 | distri_l2_name(range_restriction,set_subtraction,'DISTRI_RANRES_SETMINUS_L'). | |
| 888 | distri_l2_name(range_subtraction,union,'DISTRI_RANSUB_BUNION_L'). | |
| 889 | distri_l2_name(range_subtraction,intersection,'DISTRI_RANSUB_BINTER_L'). | |
| 890 | ||
| 891 | distribute_op(C,X,Op1,Op2,Res) :- | |
| 892 | op_to_list(X,L,Op2), | |
| 893 | distribute(C,X,L,CN,Op1), | |
| 894 | list_to_op(CN,Res,Op2). | |
| 895 | ||
| 896 | distribute(_,_,[],[],_). | |
| 897 | distribute(C,X,[D|T],[N|R],Op) :- select_op(X,C,D,N,Op), distribute(C,X,T,R,Op). | |
| 898 | ||
| 899 | distri_r3(C,Res,Rule) :- | |
| 900 | C = range_subtraction(_,X), Op1=range_subtraction, %C=..[Op1,_,X], | |
| 901 | distri_r3_name_ransub(Op2,Op3,Rule), | |
| 902 | distri_and_change(C,X,Op1,Op2,Op3,Res). | |
| 903 | distri_r3_name_ransub(union,intersection,'DISTRI_RANSUB_BUNION_R'). | |
| 904 | distri_r3_name_ransub(intersection,union,'DISTRI_RANSUB_BINTER_R'). | |
| 905 | ||
| 906 | distri_r3_info(C,Res,Rule,Info) :- | |
| 907 | C = set_subtraction(Ty,X), Op1=set_subtraction, | |
| 908 | type_expression(Ty,Info), | |
| 909 | distri_r3_name_setsub(Op2,Op3,Rule), | |
| 910 | distri_and_change(C,X,Op1,Op2,Op3,Res). | |
| 911 | distri_r3_name_setsub(intersection,union,'DERIV_TYPE_SETMINUS_BINTER'). % Ty \ (S /\ T) == (Ty \ S) \/ (Ty \ T) | |
| 912 | distri_r3_name_setsub(union,intersection,'DERIV_TYPE_SETMINUS_BUNION'). | |
| 913 | ||
| 914 | distri_l3(C,Res,Op1,Op2,Op3) :- | |
| 915 | C=..[Op1,X,_], | |
| 916 | distri_and_change(C,X,Op1,Op2,Op3,Res). | |
| 917 | ||
| 918 | % Op2 changes to Op3 | |
| 919 | distri_and_change(C,X,Op1,Op2,Op3,Res) :- | |
| 920 | functor(X,Op2,2), | |
| 921 | op_to_list(X,L,Op2), | |
| 922 | distribute(C,X,L,CN,Op1), | |
| 923 | list_to_op(CN,Res,Op3). | |
| 924 | ||
| 925 | distri_setminus(U,X,Res) :- | |
| 926 | C = set_subtraction(U,X), X = union(_,_), | |
| 927 | select_op(X,C,NewC,set_subtraction), | |
| 928 | op_to_list(NewC,CL,set_subtraction), | |
| 929 | op_to_list(X,L,union), | |
| 930 | append(CL,L,L2), | |
| 931 | list_to_op(L2,Res,set_subtraction). | |
| 932 | ||
| 933 | ||
| 934 | % ----------------- | |
| 935 | ||
| 936 | %simp_rule(X,X,'EQ'(F,N,X)) :- functor(X,F,N). | |
| 937 | ||
| 938 | % simp_rule/4 | |
| 939 | simp_rule(D,implication(negation(P),D0),'DEF_OR',OuterOp) :- OuterOp \= disjunct, D = disjunct(_,_), select_op(P,D,D0,disjunct). | |
| 940 | simp_rule(C,falsity,'SIMP_SPECIAL_AND_BFALSE',OuterOp) :- OuterOp \= conjunct, | |
| 941 | member_of_bin_op(conjunct,falsity,C). | |
| 942 | simp_rule(D,truth,'SIMP_SPECIAL_OR_BTRUE',OuterOp) :- OuterOp \= disjunct, | |
| 943 | member_of_bin_op(disjunct,truth,D). | |
| 944 | simp_rule(C,Res,'SIMP_MULTI_AND',OuterOp) :- OuterOp \= conjunct, remove_duplicates_for_op(C,Res,conjunct). | |
| 945 | simp_rule(D,Res,'SIMP_MULTI_OR',OuterOp) :- OuterOp \= disjunct, remove_duplicates_for_op(D,Res,disjunct). | |
| 946 | simp_rule(C,falsity,'SIMP_MULTI_AND_NOT',OuterOp) :- | |
| 947 | OuterOp \= conjunct, | |
| 948 | member_of(conjunct,Q,C), | |
| 949 | member_of(conjunct,NotQ,C), | |
| 950 | is_negation(Q,NotQ). | |
| 951 | simp_rule(D,truth,'SIMP_MULTI_OR_NOT',OuterOp) :- | |
| 952 | OuterOp \= disjunct, | |
| 953 | member_of(disjunct,Q,D), | |
| 954 | member_of(disjunct,NotQ,D), | |
| 955 | is_negation(Q,NotQ). | |
| 956 | simp_rule(I,empty_set,'SIMP_SPECIAL_BINTER',OuterOp) :- OuterOp \= intersection, | |
| 957 | member_of_bin_op(intersection,empty_set,I). | |
| 958 | simp_rule(I,Res,'SIMP_MULTI_BINTER',OuterOp) :- OuterOp \= intersection, remove_duplicates_for_op(I,Res,intersection). | |
| 959 | simp_rule(U,Res,'SIMP_MULTI_BUNION',OuterOp) :- OuterOp \= union, remove_duplicates_for_op(U,Res,union). | |
| 960 | simp_rule(C,empty_set,'SIMP_SPECIAL_CPROD',OuterOp) :- OuterOp \= cartesian_product, % SIMP_SPECIAL_CPROD_L / SIMP_SPECIAL_CPROD_R | |
| 961 | member_of_bin_op(cartesian_product,empty_set,C). | |
| 962 | simp_rule(C,empty_set,'SIMP_SPECIAL_FCOMP',OuterOp) :- OuterOp \= composition, | |
| 963 | member_of_bin_op(composition,empty_set,C). | |
| 964 | simp_rule(Comp,empty_set,'SIMP_SPECIAL_BCOMP',OuterOp) :- OuterOp \= ring, | |
| 965 | member_of_bin_op(ring,empty_set,Comp). | |
| 966 | simp_rule(C,Res,'DEF_BCOMP',OuterOp) :- OuterOp \= ring, C = ring(_,_), | |
| 967 | bwd_to_fwd_comp(C,Comp), reorder(Comp,Res,composition). | |
| 968 | simp_rule(P,0,'SIMP_SPECIAL_PROD_0',OuterOp) :- OuterOp \= multiplication, member_of(multiplication,0,P). | |
| 969 | simp_rule(ring(P,Q),Res,'SIMP_BCOMP_ID',OuterOp) :- OuterOp \= ring, | |
| 970 | op_to_list(ring(P,Q),List,ring), | |
| 971 | rewrite_comp_id(List,List2), | |
| 972 | list_to_op(List2,Res,ring). | |
| 973 | simp_rule(composition(P,Q),Res,'SIMP_FCOMP_ID',OuterOp) :- OuterOp \= composition, | |
| 974 | op_to_list(composition(P,Q),List,composition), | |
| 975 | rewrite_comp_id(List,List2), | |
| 976 | list_to_op(List2,Res,composition). | |
| 977 | simp_rule(Comp,Res,'DERIV_FCOMP_DOMRES',OuterOp) :- OuterOp \= composition, deriv_fcomp_dom(Comp,domain_restriction,Res). | |
| 978 | simp_rule(Comp,Res,'DERIV_FCOMP_DOMSUB',OuterOp) :- OuterOp \= composition, deriv_fcomp_dom(Comp,domain_subtraction,Res). | |
| 979 | simp_rule(Comp,Res,'DERIV_FCOMP_RANRES',OuterOp) :- OuterOp \= composition, deriv_fcomp_ran(Comp,range_restriction,Res). | |
| 980 | simp_rule(Comp,Res,'DERIV_FCOMP_RANSUB',OuterOp) :- OuterOp \= composition, deriv_fcomp_ran(Comp,range_subtraction,Res). | |
| 981 | ||
| 982 | ||
| 983 | deriv_fcomp_dom(Comp,Functor,Res) :- | |
| 984 | Comp = composition(_,_), | |
| 985 | op_to_list(Comp,List,composition), | |
| 986 | append(L,[At|R],List), | |
| 987 | At=..[Functor,P,Q], | |
| 988 | list_to_op([Q|R],RComp,composition), | |
| 989 | New=..[Functor,P,RComp], | |
| 990 | append(L,[New],ResList), | |
| 991 | list_to_op(ResList,Res,composition). | |
| 992 | ||
| 993 | deriv_fcomp_ran(Comp,Functor,Res) :- | |
| 994 | Comp = composition(_,_), | |
| 995 | op_to_list(Comp,List,composition), | |
| 996 | append(L,[At|R],List), | |
| 997 | At=..[Functor,P,Q], | |
| 998 | append(L,[P],NewL), | |
| 999 | list_to_op(NewL,LComp,composition), | |
| 1000 | New=..[Functor,LComp,Q], | |
| 1001 | list_to_op([New|R],Res,composition). | |
| 1002 | ||
| 1003 | rewrite_comp_id([X],[X]). | |
| 1004 | rewrite_comp_id([domain_restriction(S,event_b_identity),domain_restriction(T,event_b_identity)|R],Res) :- !, | |
| 1005 | rewrite_comp_id([domain_restriction(intersection(S,T),event_b_identity)|R],Res). | |
| 1006 | rewrite_comp_id([domain_restriction(S,event_b_identity),domain_subtraction(T,event_b_identity)|R],Res) :- !, | |
| 1007 | rewrite_comp_id([domain_restriction(set_subtraction(S,T),event_b_identity)|R],Res). | |
| 1008 | rewrite_comp_id([domain_subtraction(S,event_b_identity),domain_subtraction(T,event_b_identity)|R],Res) :- !, | |
| 1009 | rewrite_comp_id([domain_subtraction(union(S,T),event_b_identity)|R],Res). | |
| 1010 | rewrite_comp_id([E,F|R], [E|Res]) :- rewrite_comp_id([F|R],Res). | |
| 1011 | ||
| 1012 | ||
| 1013 | % simp_rule_with_info/4 | |
| 1014 | simp_rule_with_info(Eq,conjunct(equal(S,empty_set),equal(R,Ty)),'SIMP_DOMSUB_EQUAL_TYPE',Info) :- | |
| 1015 | is_equality(Eq,domain_subtraction(S,R),Ty), | |
| 1016 | type_expression(Ty,Info). | |
| 1017 | simp_rule_with_info(Eq,conjunct(equal(S,empty_set),equal(R,Ty)),'SIMP_RANSUB_EQUAL_TYPE',Info) :- | |
| 1018 | is_equality(Eq,range_subtraction(R,S),Ty), | |
| 1019 | type_expression(Ty,Info). | |
| 1020 | simp_rule_with_info(Eq,equal(R,reverse(Ty)),'SIMP_CONVERSE_EQUAL_TYPE',Info) :- | |
| 1021 | is_equality(Eq,reverse(R),Ty), | |
| 1022 | type_expression(Ty,Info). | |
| 1023 | simp_rule_with_info(subset(_,Ty),truth,'SIMP_TYPE_SUBSETEQ',Info) :- type_expression(Ty,Info). | |
| 1024 | simp_rule_with_info(set_subtraction(_,Ty),empty_set,'SIMP_TYPE_SETMINUS',Info) :- type_expression(Ty,Info). | |
| 1025 | simp_rule_with_info(set_subtraction(Ty,set_subtraction(Ty,S)),S,'SIMP_TYPE_SETMINUS_SETMINUS',Info) :- type_expression(Ty,Info). | |
| 1026 | simp_rule_with_info(member(_,Ty),truth,'SIMP_TYPE_IN',Info) :- type_expression(Ty,Info). | |
| 1027 | simp_rule_with_info(subset_strict(S,Ty),not_equal(S,Ty),'SIMP_TYPE_SUBSET_L',Info) :- type_expression(Ty,Info). | |
| 1028 | simp_rule_with_info(Eq,conjunct(equal(A,Ty),equal(B,empty_set)),'SIMP_SETMINUS_EQUAL_TYPE',Info) :- | |
| 1029 | is_equality(Eq,set_subtraction(A,B),Ty), | |
| 1030 | type_expression(Ty,Info). | |
| 1031 | simp_rule_with_info(Eq,Res,'SIMP_BINTER_EQUAL_TYPE',Info) :- | |
| 1032 | is_equality(Eq,I,Ty), | |
| 1033 | I = intersection(_,_), | |
| 1034 | type_expression(Ty,Info), | |
| 1035 | and_equal_type(I,Ty,Res). | |
| 1036 | simp_rule_with_info(Eq,equal(S,set_extension([Ty])),'SIMP_KINTER_EQUAL_TYPE',Info) :- | |
| 1037 | is_equality(Eq,general_intersection(S),Ty), | |
| 1038 | type_expression(Ty,Info). | |
| 1039 | simp_rule_with_info(Expr,falsity,'SIMP_TYPE_EQUAL_EMPTY',Info) :- is_empty(Expr,Ty), type_expression(Ty,Info). | |
| 1040 | simp_rule_with_info(Eq,forall([X],P,equal(E,Ty)),'SIMP_QINTER_EQUAL_TYPE',Info) :- | |
| 1041 | is_equality(Eq,quantified_intersection([X],P,E),Ty), | |
| 1042 | type_expression(Ty,Info). | |
| 1043 | simp_rule_with_info(I,S,'SIMP_TYPE_BINTER',Info) :- (I = intersection(S,Ty) ; I = intersection(Ty,S)), type_expression(Ty,Info). | |
| 1044 | simp_rule_with_info(Eq,falsity,'SIMP_TYPE_EQUAL_RELDOMRAN',Info) :- | |
| 1045 | is_equality(Eq,R,Ty), | |
| 1046 | type_expression(Ty,Info), | |
| 1047 | is_rel(R,_,_,_), | |
| 1048 | functor(R,Op,2), | |
| 1049 | \+ member(Op,[relations,partial_function,partial_injection]). % TODO: use facts without functor | |
| 1050 | simp_rule_with_info(member(Prj,RT),truth,Rule,Info) :- | |
| 1051 | (Prj = event_b_first_projection_v2, Rule = 'DERIV_PRJ1_SURJ' | |
| 1052 | ; Prj = event_b_second_projection_v2, Rule = 'DERIV_PRJ2_SURJ'), | |
| 1053 | is_rel(RT,_,Ty1,Ty2), | |
| 1054 | \+ is_inj(RT,Ty1,Ty2), | |
| 1055 | type_expression(Ty1,Info), | |
| 1056 | type_expression(Ty2,Info). | |
| 1057 | simp_rule_with_info(member(event_b_identity,RT),truth,'DERIV_ID_BIJ',Info) :- is_rel(RT,_,Ty,Ty), type_expression(Ty,Info). | |
| 1058 | simp_rule_with_info(domain_restriction(Ty,R),R,'SIMP_TYPE_DOMRES',Info) :- type_expression(Ty,Info). | |
| 1059 | simp_rule_with_info(range_restriction(R,Ty),R,'SIMP_TYPE_RANRES',Info) :- type_expression(Ty,Info). | |
| 1060 | simp_rule_with_info(domain_subtraction(Ty,R),R,'SIMP_TYPE_DOMSUB',Info) :- type_expression(Ty,Info). | |
| 1061 | simp_rule_with_info(range_subtraction(R,Ty),R,'SIMP_TYPE_RANSUB',Info) :- type_expression(Ty,Info). | |
| 1062 | simp_rule_with_info(image(R,Ty),range(R),'SIMP_TYPE_RELIMAGE',Info) :- type_expression(Ty,Info). | |
| 1063 | simp_rule_with_info(composition(R,Ty),cartesian_product(domain(R),Tb),'SIMP_TYPE_FCOMP_R',Info) :- | |
| 1064 | type_expression(Ty,Info), | |
| 1065 | Ty = cartesian_product(_,Tb). | |
| 1066 | simp_rule_with_info(composition(Ty,R),cartesian_product(Ta,range(R)),'SIMP_TYPE_FCOMP_L',Info) :- | |
| 1067 | type_expression(Ty,Info), | |
| 1068 | Ty = cartesian_product(Ta,_). | |
| 1069 | simp_rule_with_info(ring(Ty,R),cartesian_product(domain(R),Tb),'SIMP_TYPE_BCOMP_L',Info) :- | |
| 1070 | type_expression(Ty,Info), | |
| 1071 | Ty = cartesian_product(_,Tb). | |
| 1072 | simp_rule_with_info(ring(R,Ty),cartesian_product(Ta,range(R)),'SIMP_TYPE_BCOMP_R',Info) :- | |
| 1073 | type_expression(Ty,Info), | |
| 1074 | Ty = cartesian_product(Ta,_). | |
| 1075 | simp_rule_with_info(domain(Ty),Ta,'SIMP_TYPE_DOM',Info) :- Ty = cartesian_product(Ta,_), type_expression(Ty,Info). | |
| 1076 | simp_rule_with_info(range(Ty),Tb,'SIMP_TYPE_RAN',Info) :- Ty = cartesian_product(_,Tb), type_expression(Ty,Info). | |
| 1077 | simp_rule_with_info(Eq,conjunct(equal(S,Ta),equal(T,Tb)),'SIMP_CPROD_EQUAL_TYPE',Info) :- | |
| 1078 | is_equality(Eq,cartesian_product(S,T),Ty), | |
| 1079 | Ty = cartesian_product(Ta,Tb), | |
| 1080 | type_expression(Ty,Info). | |
| 1081 | simp_rule_with_info(Eq,conjunct(equal(S,Ta),equal(T,Tb)),'SIMP_TYPE_EQUAL_REL',Info) :- | |
| 1082 | is_equality(Eq,relations(S,T),Ty), | |
| 1083 | Ty = cartesian_product(Ta,Tb), | |
| 1084 | type_expression(Ty,Info). | |
| 1085 | simp_rule_with_info(Eq,conjunct(equal(S,Ta),equal(R,Ty)),'SIMP_DOMRES_EQUAL_TYPE',Info) :- | |
| 1086 | is_equality(Eq,domain_restriction(S,R),Ty), | |
| 1087 | Ty = cartesian_product(Ta,_), | |
| 1088 | type_expression(Ty,Info). | |
| 1089 | simp_rule_with_info(Eq,conjunct(equal(S,Tb),equal(R,Ty)),'SIMP_RANRES_EQUAL_TYPE',Info) :- | |
| 1090 | is_equality(Eq,range_restriction(R,S),Ty), | |
| 1091 | Ty = cartesian_product(_,Tb), | |
| 1092 | type_expression(Ty,Info). | |
| 1093 | simp_rule_with_info(Eq,conjunct(equal(P,cartesian_product(Ta,Tb)),equal(Q,cartesian_product(Ta,Tc))),'SIMP_DPROD_EQUAL_TYPE',Info) :- | |
| 1094 | is_equality(Eq,direct_product(P,Q),Ty), | |
| 1095 | Ty = cartesian_product(Ta,cartesian_product(Tb,Tc)), | |
| 1096 | type_expression(Ty,Info). | |
| 1097 | simp_rule_with_info(Eq,conjunct(equal(P,cartesian_product(Ta,Tc)),equal(Q,cartesian_product(Tb,Td))),'SIMP_PPROD_EQUAL_TYPE',Info) :- | |
| 1098 | is_equality(Eq,parallel_product(P,Q),Ty), | |
| 1099 | Ty = cartesian_product(cartesian_product(Ta,Tb),cartesian_product(Tc,Td)), | |
| 1100 | type_expression(Ty,Info). | |
| 1101 | simp_rule_with_info(set_subtraction(Ty,set_subtraction(S,T)),union(set_subtraction(Ty,S),T),'DERIV_TYPE_SETMINUS_SETMINUS',Info) :- | |
| 1102 | type_expression(Ty,Info). | |
| 1103 | simp_rule_with_info(Ex,disjunct(less(E,F),greater(E,F)),'DERIV_NOT_EQUAL',Info) :- | |
| 1104 | (Ex = negation(equal(E,F)) ; Ex = not_equal(E,F)), | |
| 1105 | get_meta_info(ids_types,Info,IdsTypes), | |
| 1106 | check_type(E,F,IdsTypes,integer). | |
| 1107 | simp_rule_with_info(equal(S,T),conjunct(subset(S,T),subset(T,S)),'DERIV_EQUAL',Info) :- | |
| 1108 | get_meta_info(ids_types,Info,IdsTypes), | |
| 1109 | check_type(S,T,IdsTypes,set(_)). | |
| 1110 | simp_rule_with_info(subset(S,T),subset(set_subtraction(Ty,T),set_subtraction(Ty,S)),'DERIV_SUBSETEQ',Info) :- | |
| 1111 | get_meta_info(ids_types,Info,IdsTypes), | |
| 1112 | check_type(S,T,IdsTypes,Type), | |
| 1113 | get_type_expression(Type,pow_subset(Ty)). | |
| 1114 | /* simp_rule_with_info(event_b_comprehension_set(Ids,E,truth),Ty,'SIMP_SPECIAL_COMPSET_BTRUE',Info) :- | |
| 1115 | get_meta_info(ids_types,Info,IdsTypes), % IdsTypes does not contain bound identifiers | |
| 1116 | pairwise_distict(E,Ids), | |
| 1117 | check_type(E,IdsTypes,Type), | |
| 1118 | get_type_expression(Type,Ty). */ | |
| 1119 | simp_rule_with_info(C,Res,Rule,Info) :- distri_r3_info(C,Res,Rule,Info). | |
| 1120 | ||
| 1121 | ||
| 1122 | %pairwise_distict(E,Ids) :- pairwise_distict(E,Ids,_). | |
| 1123 | % | |
| 1124 | %pairwise_distict(couple(E,F),Ids,Ids1) :- pairwise_distict(E,Ids,Ids0), pairwise_distict(F,Ids0,Ids1). | |
| 1125 | %pairwise_distict(E,Ids,Ids0) :- E = '$'(X), atomic(X), select(E,Ids,Ids0). | |
| 1126 | ||
| 1127 | check_type('$'(S),_,IdsTypes,Type) :- !, member(b(identifier(S),Type,_),IdsTypes). | |
| 1128 | check_type(_,'$'(T),IdsTypes,Type) :- !, member(b(identifier(T),Type,_),IdsTypes). | |
| 1129 | check_type(S,_,IdsTypes,Type) :- check_type(S,IdsTypes,Type). | |
| 1130 | check_type(S,IdsTypes,Type) :- | |
| 1131 | new_aux_identifier(IdsTypes,X), | |
| 1132 | get_typed_identifiers(equal('$'(X),S),[identifier(IdsTypes)],L), | |
| 1133 | member(b(identifier(X),Type,_),L). | |
| 1134 | ||
| 1135 | ||
| 1136 | % simp_rule_with_descr/4 | |
| 1137 | simp_rule_with_descr(couple(function(event_b_first_projection_v2,E),function(event_b_second_projection_v2,F)),E,Rule,Rule) :- | |
| 1138 | Rule = 'SIMP_MAPSTO_PRJ1_PRJ2', | |
| 1139 | equal_terms(E,F). | |
| 1140 | simp_rule_with_descr(domain(successor),Z,Rule,Rule) :- Rule = 'SIMP_DOM_SUCC', is_integer_set(Z). | |
| 1141 | simp_rule_with_descr(range(successor),Z,Rule,Rule) :- Rule = 'SIMP_RAN_SUCC', is_integer_set(Z). | |
| 1142 | simp_rule_with_descr(predecessor,reverse(successor),Rule,Rule) :- Rule = 'DEF_PRED'. | |
| 1143 | simp_rule_with_descr(Expr,negation(member(A,SetB)),'SIMP_BINTER_SING_EQUAL_EMPTY'(A),Descr) :- | |
| 1144 | is_empty(Expr,Inter), | |
| 1145 | is_inter(Inter,SetA,SetB), | |
| 1146 | singleton_set(SetA,A), | |
| 1147 | create_descr('SIMP_BINTER_SING_EQUAL_EMPTY',A,Descr). | |
| 1148 | ||
| 1149 | ||
| 1150 | ||
| 1151 | % simp_rule_with_hyps/4 without info | |
| 1152 | simp_rule_with_hyps(domain(R),E,'DERIV_DOM_TOTALREL',Hyps) :- % derive domain of a total relation | |
| 1153 | member_hyps(member(R,FT),Hyps), is_rel(FT,total,E,_). | |
| 1154 | simp_rule_with_hyps(range(R),F,'DERIV_RAN_SURJREL',Hyps) :- % derive range of a surjective relation | |
| 1155 | member_hyps(member(R,FT),Hyps), is_surj(FT,_,F). | |
| 1156 | simp_rule_with_hyps(function(domain_restriction(_,F),G),function(F,G),'SIMP_FUNIMAGE_DOMRES',Hyps) :- | |
| 1157 | member_hyps(member(F,FT),Hyps), is_fun(FT,_,_,_). | |
| 1158 | simp_rule_with_hyps(function(domain_subtraction(_,F),G),function(F,G),'SIMP_FUNIMAGE_DOMSUB',Hyps) :- | |
| 1159 | member_hyps(member(F,FT),Hyps), is_fun(FT,_,_,_). | |
| 1160 | simp_rule_with_hyps(function(range_restriction(F,_),G),function(F,G),'SIMP_FUNIMAGE_RANRES',Hyps) :- | |
| 1161 | member_hyps(member(F,FT),Hyps), is_fun(FT,_,_,_). | |
| 1162 | simp_rule_with_hyps(function(range_subtraction(F,_),G),function(F,G),'SIMP_FUNIMAGE_RANSUB',Hyps) :- | |
| 1163 | member_hyps(member(F,FT),Hyps), is_fun(FT,_,_,_). | |
| 1164 | simp_rule_with_hyps(function(set_subtraction(F,_),G),function(F,G),'SIMP_FUNIMAGE_SETMINUS',Hyps) :- | |
| 1165 | member_hyps(member(F,FT),Hyps), is_fun(FT,_,_,_). | |
| 1166 | simp_rule_with_hyps(card(set_subtraction(S,T)),minus(card(S),card(T)),'SIMP_CARD_SETMINUS',Hyps) :- | |
| 1167 | member_hyps(subset(T,S),Hyps), | |
| 1168 | (member_hyps(finite(T),Hyps) | |
| 1169 | ; member_hyps(finite(S),Hyps)). | |
| 1170 | simp_rule_with_hyps(card(set_subtraction(S,set_extension(L))),minus(card(S),card(set_extension(L))),Rule,Hyps) :- | |
| 1171 | Rule = 'SIMP_CARD_SETMINUS_SETENUM', | |
| 1172 | all_in_set(L,S,Hyps). | |
| 1173 | simp_rule_with_hyps(L,less(A,B),'DERIV_LESS',Hyps) :- % A<=B & A/=B => A<B, own rule (not in Rodin Event-B Wiki) | |
| 1174 | is_less_eq(L,A,B), is_inequality(Ex,A,B), member(Ex,Hyps). | |
| 1175 | % allow simplifications deeper inside the term: | |
| 1176 | simp_rule_with_hyps(C,NewC,Rule,Hyps) :- C=..[F,P], simp_rule_with_hyps(P,Q,Rule,Hyps), NewC=..[F,Q]. | |
| 1177 | simp_rule_with_hyps(C,NewC,Rule,Hyps) :- C=..[F,P,R], simp_rule_with_hyps(P,Q,Rule,Hyps), NewC=..[F,Q,R]. | |
| 1178 | simp_rule_with_hyps(C,NewC,Rule,Hyps) :- C=..[F,R,P], simp_rule_with_hyps(P,Q,Rule,Hyps), NewC=..[F,R,Q]. | |
| 1179 | ||
| 1180 | ||
| 1181 | % ----------------------- | |
| 1182 | ||
| 1183 | or_equal([],_,D,D). | |
| 1184 | or_equal([A|L],E,D,Res) :- or_equal(L,E,disjunct(D,equal(E,A)),Res). | |
| 1185 | ||
| 1186 | and_empty(C,Conj,Op) :- C=..[Op,A,B], and_empty(A,ConjA,Op), and_empty(B,ConjB,Op), !, Conj = conjunct(ConjA,ConjB). | |
| 1187 | and_empty(A,equal(A,empty_set),_). | |
| 1188 | ||
| 1189 | and_imp(C,R,Conj,Op) :- C=..[Op,A,B], and_imp(A,R,ConjA,Op), and_imp(B,R,ConjB,Op), !, Conj = conjunct(ConjA,ConjB). | |
| 1190 | and_imp(A,R,implication(R,A),conjunct). | |
| 1191 | and_imp(A,R,implication(A,R),disjunct). | |
| 1192 | ||
| 1193 | union_subset(S,union(A,B),Conj) :- union_subset(S,A,ConjA), union_subset(S,B,ConjB), !, Conj = conjunct(ConjA,ConjB). | |
| 1194 | union_subset(S,A,subset(A,S)). | |
| 1195 | ||
| 1196 | union_subset_member(T,union(A,B),Conj) :- | |
| 1197 | union_subset_member(T,A,ConjA), | |
| 1198 | union_subset_member(T,B,ConjB),!, | |
| 1199 | Conj = conjunct(ConjA,ConjB). | |
| 1200 | union_subset_member(T,SetF,member(F,T)) :- singleton_set(SetF,F), !. | |
| 1201 | union_subset_member(T,A,subset(A,T)). | |
| 1202 | ||
| 1203 | ||
| 1204 | member_union(E,union(A,B),Disj) :- member_union(E,A,DisjA), member_union(E,B,DisjB), !, Disj = disjunct(DisjA,DisjB). | |
| 1205 | member_union(E,A,member(E,A)). | |
| 1206 | ||
| 1207 | subset_inter(S,intersection(A,B),Conj) :- subset_inter(S,A,ConjA), subset_inter(S,B,ConjB), Conj = conjunct(ConjA,ConjB), !. | |
| 1208 | subset_inter(S,A,subset(S,A)). | |
| 1209 | ||
| 1210 | member_intersection(E,intersection(A,B),Conj) :- | |
| 1211 | member_intersection(E,A,ConjA), | |
| 1212 | member_intersection(E,B,ConjB),!, | |
| 1213 | Conj = conjunct(ConjA,ConjB). | |
| 1214 | member_intersection(E,A,member(E,A)). | |
| 1215 | ||
| 1216 | distribute_exists(X,disjunct(A,B),Disj) :- distribute_exists(X,A,DisjA), distribute_exists(X,B,DisjB), !, Disj = disjunct(DisjA,DisjB). | |
| 1217 | distribute_exists(X,P,exists(X,P)). | |
| 1218 | ||
| 1219 | distribute_forall(X,P,conjunct(A,B),Conj) :- | |
| 1220 | distribute_forall(X,P,A,ConjA), | |
| 1221 | distribute_forall(X,P,B,ConjB),!, | |
| 1222 | Conj = conjunct(ConjA,ConjB). | |
| 1223 | distribute_forall(X,P,A,forall(X,P,A)). | |
| 1224 | ||
| 1225 | distribute_binary_minus(minus(X,Y),add(X,YY)) :- distribute_unary_minus(Y,YY). | |
| 1226 | ||
| 1227 | distribute_unary_minus(add(Y,Z),minus(YY,Z)) :- !, distribute_unary_minus(Y,YY). | |
| 1228 | distribute_unary_minus(minus(Y,Z),add(YY,Z)) :- !, distribute_unary_minus(Y,YY). | |
| 1229 | distribute_unary_minus(add(unary_minus(Y),Z),minus(YY,Z)) :- !, distribute_unary_minus(unary_minus(Y),YY). | |
| 1230 | distribute_unary_minus(minus(unary_minus(Y),Z),add(YY,Z)) :- !, distribute_unary_minus(unary_minus(Y),YY). | |
| 1231 | distribute_unary_minus(unary_minus(Y),Y) :- !. | |
| 1232 | distribute_unary_minus(Y,unary_minus(Y)). | |
| 1233 | ||
| 1234 | ||
| 1235 | left_associate_additions(add(X,Expr),Res) :- | |
| 1236 | \+ leftmost_term(Expr,_,_), !, | |
| 1237 | normalize_minus(add(X,Expr),Res). | |
| 1238 | left_associate_additions(add(X,Expr),Res) :- | |
| 1239 | leftmost_term(Expr,Term,Rest), !, | |
| 1240 | normalize_minus(add(add(X,Term),Rest),NewTerm), | |
| 1241 | left_associate_additions(NewTerm,Res). | |
| 1242 | left_associate_additions(X,X). | |
| 1243 | ||
| 1244 | leftmost_term(C,Term,Res) :- | |
| 1245 | C=..[Op,A,B], (Op = add ; Op = minus), | |
| 1246 | functor(A,OpA,2), (OpA = add ; OpA = minus),!, | |
| 1247 | leftmost_term(A,Term,Rest), | |
| 1248 | Res=..[Op,Rest,B]. | |
| 1249 | leftmost_term(add(X,Y),X,Y). | |
| 1250 | leftmost_term(minus(X,Y),X,unary_minus(Y)). | |
| 1251 | ||
| 1252 | normalize_minus(add(X,unary_minus(Y)),minus(XX,Y)) :- !, | |
| 1253 | normalize_minus(X,XX). | |
| 1254 | normalize_minus(Term,Result) :- | |
| 1255 | Term=..[F|Args], !, | |
| 1256 | maplist(normalize_minus,Args,NewArgs), | |
| 1257 | Result=..[F|NewArgs]. | |
| 1258 | normalize_minus(X,X). | |
| 1259 | ||
| 1260 | member_couples(E,F,[Q],_,[member(couple(E,F),Q)]). | |
| 1261 | member_couples(E,F,[P|Q],[X|T],[member(couple(E,X),P)|R]) :- member_couples(X,F,Q,T,R). | |
| 1262 | ||
| 1263 | distri_reverse(C,U,Op) :- C=..[Op,A,B], distri_reverse(A,UA,Op), distri_reverse(B,UB,Op), !, U=..[Op,UA,UB]. | |
| 1264 | distri_reverse(A,reverse(A),_). | |
| 1265 | ||
| 1266 | distri_reverse_reverse(C,U,Op) :- C=..[Op,A,B], distri_reverse_reverse(A,UA,Op), distri_reverse_reverse(B,UB,Op), !, U=..[Op,UB,UA]. | |
| 1267 | distri_reverse_reverse(A,reverse(A),_). | |
| 1268 | ||
| 1269 | distri_union(union(A,B),Union,Op) :- distri_union(A,L,Op), distri_union(B,R,Op), !, Union = union(L,R). | |
| 1270 | distri_union(A,C,Op) :- C=..[Op,A]. | |
| 1271 | ||
| 1272 | image_union(F,union(A,B),Union) :- image_union(F,A,L), image_union(F,B,R), !, Union = union(L,R). | |
| 1273 | image_union(F,A,image(F,A)). | |
| 1274 | ||
| 1275 | union_image(union(A,B),S,Union) :- union_image(A,S,L), union_image(B,S,R), !, Union = union(L,R). | |
| 1276 | union_image(A,S,image(A,S)). | |
| 1277 | ||
| 1278 | finite_union(union(A,B),Conj) :- finite_union(A,ConjA), finite_union(B,ConjB), !, Conj = conjunct(ConjA,ConjB). | |
| 1279 | finite_union(S,finite(S)). | |
| 1280 | ||
| 1281 | ||
| 1282 | last_overwrite(overwrite(_,B),Res) :- !, last_overwrite(B,Res). | |
| 1283 | last_overwrite(B,B). | |
| 1284 | ||
| 1285 | and_equal_type(intersection(A,B),Ty,Conj) :- and_equal_type(A,Ty,L), and_equal_type(B,Ty,R), !, Conj = conjunct(L,R). | |
| 1286 | and_equal_type(A,Ty,equal(A,Ty)). | |
| 1287 | ||
| 1288 | bwd_to_fwd_comp(ring(R,S),Res) :- | |
| 1289 | bwd_to_fwd_comp(R,R2), | |
| 1290 | bwd_to_fwd_comp(S,S2), | |
| 1291 | Res = composition(S2,R2). | |
| 1292 | bwd_to_fwd_comp(X,X) :- X \= ring(_,_). | |
| 1293 | ||
| 1294 | % ------------------ | |
| 1295 | ||
| 1296 | % change order of operation if Op is associative | |
| 1297 | reorder(C,Res,Op) :- | |
| 1298 | C=..[Op,A,B], | |
| 1299 | B=..[Op,L,Rest],!, | |
| 1300 | R=..[Op,A,L], | |
| 1301 | append_to_op(Rest,R,Res,Op). | |
| 1302 | reorder(C,C,Op) :- functor(C,Op,2). | |
| 1303 | ||
| 1304 | append_to_op(C,R,Res,Op) :- | |
| 1305 | C=..[Op,A,B], | |
| 1306 | Inner=..[Op,R,A],!, | |
| 1307 | append_to_op(B,Inner,Res,Op). | |
| 1308 | append_to_op(B,R,C,Op) :- C=..[Op,R,B]. | |
| 1309 | ||
| 1310 | % ------------------ | |
| 1311 | ||
| 1312 | remove_from_op(El,Term,NewTerm,Op) :- | |
| 1313 | op_to_list(Term,List,Op), | |
| 1314 | remove_from_list(El,List,List0), | |
| 1315 | list_to_op(List0,NewTerm,Op). | |
| 1316 | ||
| 1317 | remove_from_list(_,[],[]). | |
| 1318 | remove_from_list(E,[E|T],T2) :- remove_from_list(E,T,T2). | |
| 1319 | remove_from_list(E,[X|T],[X|T2]) :- X \= E, remove_from_list(E,T,T2). | |
| 1320 | ||
| 1321 |