| 1 | % (c) 2014-2022 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(kodkod_rewrite,[ apply_rewriting_rules/2 ]). | |
| 6 | ||
| 7 | :- use_module(probsrc(module_information),[module_info/2]). | |
| 8 | :- module_info(group,kodkod). | |
| 9 | :- module_info(description,'This module contains rewriting rules that are applied during tge translation to Kodkod.'). | |
| 10 | ||
| 11 | :- use_module(library(lists)). | |
| 12 | :- use_module(probsrc(bsyntaxtree)). | |
| 13 | :- use_module(kodkod_tools). | |
| 14 | ||
| 15 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| 16 | % applying re-writing rules to make some statements translatable to Kodkod | |
| 17 | ||
| 18 | apply_rewriting_rules(TExpr,NTExpr) :- | |
| 19 | remove_bt(TExpr,Expr,NExpr,NTExpr), | |
| 20 | get_texpr_info(TExpr,Info), | |
| 21 | apply_rewriting_rules_pre(Expr,Info,IExpr), | |
| 22 | syntaxtransformation(IExpr,Subs,_,NSubs,Expr1), | |
| 23 | maplist(apply_rewriting_rules,Subs,NSubs), | |
| 24 | apply_rewriting_rules_post(Expr1,Info,NExpr). | |
| 25 | apply_rewriting_rules_pre(Expr,Info,NExpr) :- | |
| 26 | kodkod_rewrite_pre(Expr,Info,Expr1),!, | |
| 27 | apply_rewriting_rules_pre(Expr1,Info,NExpr). | |
| 28 | apply_rewriting_rules_pre(Expr,_,Expr). | |
| 29 | apply_rewriting_rules_post(Expr,Info,NExpr) :- | |
| 30 | kodkod_rewrite_post(Expr,Info,Expr1),!, | |
| 31 | apply_rewriting_rules_post(Expr1,Info,NExpr). | |
| 32 | apply_rewriting_rules_post(Expr,_,Expr). | |
| 33 | ||
| 34 | :- use_module(probsrc(bsyntaxtree),[get_texpr_set_type/2, replace_ids_by_exprs/4]). | |
| 35 | kodkod_rewrite_pre(let_expression(Ids,Exprs,Body),_,Res) :- !, % expand LET expression | |
| 36 | replace_ids_by_exprs(Body,Ids,Exprs,b(NewBody,_,I2)), | |
| 37 | (kodkod_rewrite_pre(NewBody,I2,Res2) -> Res=Res2; Res = NewBody). | |
| 38 | kodkod_rewrite_pre(let_predicate(Ids,Exprs,Body),_,Res) :- !, % expand LET predicate | |
| 39 | replace_ids_by_exprs(Body,Ids,Exprs,b(NewBody,_,I2)), | |
| 40 | (kodkod_rewrite_pre(NewBody,I2,Res2) -> Res=Res2; Res = NewBody). | |
| 41 | kodkod_rewrite_pre(not_equal(A,B),_,negation(Equal)) :- !, | |
| 42 | create_kk_tpred(equal(A,B),Equal). | |
| 43 | kodkod_rewrite_pre(member(Elem,Powset),_,Result) :- | |
| 44 | get_texpr_expr(Powset,PExpr), | |
| 45 | get_texpr_info(Elem,ElemInfo), | |
| 46 | ? | kodkod_rewrite_membership(PExpr,Elem,ElemInfo,Result), |
| 47 | !. | |
| 48 | kodkod_rewrite_pre(subset(Subset,Powset),_,forall([Elem],TPre,TCond)) :- | |
| 49 | get_texpr_info(Subset,Info), | |
| 50 | get_texpr_set_type(Subset,ElemType), | |
| 51 | unique_identifier(TId), | |
| 52 | element_analysis(Info,ElemInfo), | |
| 53 | create_texpr(identifier(TId),ElemType,ElemInfo,Elem), | |
| 54 | get_texpr_expr(Powset,PExpr), | |
| 55 | kodkod_rewrite_membership(PExpr,Elem,ElemInfo,Cond),!, | |
| 56 | create_texpr(member(Elem,Subset),pred,[],TPre), | |
| 57 | create_texpr(Cond,pred,[],TCond). | |
| 58 | kodkod_rewrite_pre(size(Seq),_,card(Seq)) :- !. | |
| 59 | kodkod_rewrite_post(interval(A,B),Info,comprehension_set([TmpId],Predicate)) :- !, | |
| 60 | element_analysis(Info,ElemInfo), | |
| 61 | unique_identifier(TId), | |
| 62 | create_texpr(identifier(TId),integer,ElemInfo,TmpId), | |
| 63 | create_texpr(less_equal(A,TmpId),pred,[],Left), | |
| 64 | create_texpr(less_equal(TmpId,B),pred,[],Right), | |
| 65 | conjunct_predicates([Left,Right],Predicate). | |
| 66 | kodkod_rewrite_post(sequence_extension(Elems),_Info,set_extension(Pairs)) :- !, | |
| 67 | convert_elements_to_pairs(Elems,1,Pairs). | |
| 68 | kodkod_rewrite_post(general_sum([TId],Pred,Expr),_Info,general_sum([TId],NPred,Expr)) :- | |
| 69 | get_texpr_id(TId,Id), get_texpr_id(TElem,Id), | |
| 70 | extract_finite_integer_range(TId,[],IRange), | |
| 71 | \+ get_texpr_expr(Pred,member(TElem,_TSet)),!, | |
| 72 | write('rewritten\n'), | |
| 73 | create_texpr(comprehension_set([TId],Pred),set(integer),[analysis([elem(interval):IRange])], | |
| 74 | TCompSet), | |
| 75 | create_texpr(member(TId,TCompSet),pred,[],NPred). | |
| 76 | convert_elements_to_pairs([],_,[]). | |
| 77 | convert_elements_to_pairs([Elem|Erest],Index,[Pair|Prest]) :- | |
| 78 | convert_element_to_pair(Elem,Index,Pair), | |
| 79 | I2 is Index + 1, | |
| 80 | convert_elements_to_pairs(Erest,I2,Prest). | |
| 81 | convert_element_to_pair(Elem,Index,Pair) :- | |
| 82 | Range = irange(Index,Index), | |
| 83 | create_texpr(integer(Index),integer,[analysis([interval:Range])],TIndex), | |
| 84 | get_texpr_type(Elem,Type), | |
| 85 | get_texpr_info(Elem,EInfo), | |
| 86 | findall(right(Scope):Info, | |
| 87 | ( memberchk(analysis(AInfos),EInfo),member(Scope:Info,AInfos)), | |
| 88 | RInfos), | |
| 89 | create_texpr(couple(TIndex,Elem),couple(integer,Type),[analysis([left(interval):Range|RInfos])],Pair). | |
| 90 | ||
| 91 | kodkod_rewrite_membership(pow_subset(Set),Elem,_,subset(Elem,Set)). | |
| 92 | kodkod_rewrite_membership(fin_subset(Set),Elem,_,subset(Elem,Set)). | |
| 93 | kodkod_rewrite_membership(relations(A,B),Elem,_,subset(Elem,Cartesian)) :- | |
| 94 | create_kk_tpred(cartesian_product(A,B),Cartesian). | |
| 95 | kodkod_rewrite_membership(pow1_subset(Set),Elem,ElemInfo,conjunct(Subset,Exists)) :- | |
| 96 | get_texpr_set_type(Set,Type), | |
| 97 | create_texpr(identifier('___elem'),Type,[kodkod|ElemInfo],Id), | |
| 98 | create_kk_tpred(subset(Elem,Set),Subset), | |
| 99 | create_kk_tpred(exists([Id],Member),Exists), | |
| 100 | create_kk_tpred(member(Id,Set),Member). | |
| 101 | kodkod_rewrite_membership(fin1_subset(Set),Elem,Info,Pred) :- | |
| 102 | kodkod_rewrite_membership(pow1_subset(Set),Elem,Info,Pred). | |
| 103 | kodkod_rewrite_membership(interval(A,B),Elem,_,conjunct(Lower,Upper)) :- | |
| 104 | create_kk_tpred(less_equal(A,Elem),Lower), | |
| 105 | create_kk_tpred(less_equal(Elem,B),Upper). | |
| 106 | kodkod_rewrite_membership(integer_set('NATURAL'),Elem,_,less_equal(Zero,Elem)) :- | |
| 107 | create_integer_with_analysis(0,Zero). | |
| 108 | kodkod_rewrite_membership(integer_set('NATURAL1'),Elem,_,less_equal(One,Elem)) :- | |
| 109 | create_integer_with_analysis(1,One). | |
| 110 | create_kk_tpred(Pred,TPred) :- | |
| 111 | create_texpr(Pred,pred,[kodkod],TPred). | |
| 112 | create_integer_with_analysis(I,Expr) :- | |
| 113 | create_texpr(integer(I),integer,[analysis([interval:irange(I,I)])],Expr). | |
| 114 | ||
| 115 | element_analysis(SetInfo,[analysis(MemberInfo)]) :- | |
| 116 | findall( S:R, | |
| 117 | ( member(analysis(Analysis), SetInfo), | |
| 118 | member(elem(S):R,Analysis)), | |
| 119 | MemberInfo). |