1 | % (c) 2009-2013 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(units_prettyprint, [units_pp_trans/2, | |
6 | units_pp_prop/2, | |
7 | units_pp_value/2, | |
8 | pp/3, | |
9 | pp_fixpoint_result/3 | |
10 | ]). | |
11 | ||
12 | :- use_module(library(codesio)). | |
13 | :- use_module(library(lists)). | |
14 | :- use_module(library(avl)). | |
15 | ||
16 | :- use_module(probsrc(tools)). | |
17 | :- use_module(probsrc(error_manager)). | |
18 | ||
19 | :- use_module(units_alias). | |
20 | :- use_module(units_tools). | |
21 | :- use_module(units). | |
22 | :- use_module(units_interpreter). | |
23 | ||
24 | :- use_module(probsrc(module_information)). | |
25 | :- module_info(group,plugin_units). | |
26 | :- module_info(description,'Units Plugin: Prettyprinter for properties and transitions'). | |
27 | ||
28 | units_pp_trans(Transition,Pretty) :- | |
29 | %write(units_pp_trans(Transition,Pretty)), | |
30 | pp(classic,Transition,PrettyTerm), | |
31 | write_to_codes(PrettyTerm,Pretty). | |
32 | ||
33 | units_pp_prop(Property,Pretty) :- | |
34 | pp(classic,Property,PrettyTerm), | |
35 | write_to_codes(PrettyTerm,Pretty). | |
36 | ||
37 | units_pp_value(Value,Pretty) :- | |
38 | pp(classic,Value,PrettyTerm), | |
39 | write_to_codes(PrettyTerm,Pretty). | |
40 | ||
41 | ||
42 | pp(_ClassicOrEventB,X,unknown) :- var(X), !. | |
43 | pp(ClassicOrEventB,integer(X),Y) :- !, pp(ClassicOrEventB,X,Y). | |
44 | pp(ClassicOrEventB,int(X),Y) :- !, pp(ClassicOrEventB,X,Y). | |
45 | pp(ClassicOrEventB,boolean(X),Y) :- !, pp(ClassicOrEventB,X,Y). | |
46 | pp(ClassicOrEventB,string(X),Y) :- !, pp(ClassicOrEventB,X,Y). | |
47 | pp(ClassicOrEventB,global_set(X),Y) :- !, pp(ClassicOrEventB,X,Y). | |
48 | pp(ClassicOrEventB,set(X),Y) :- !, pp(ClassicOrEventB,X,Y). | |
49 | pp(ClassicOrEventB,couple(X,Y),Pretty) :- !, | |
50 | pp(ClassicOrEventB,X,PPX), pp(ClassicOrEventB,Y,PPY), | |
51 | ajoin([PPX, ' -> ', PPY],Pretty). | |
52 | pp(ClassicOrEventB,global(X,_Y),Pretty) :- !, | |
53 | pp(ClassicOrEventB,X,Pretty). | |
54 | % in the tcltk interface, the error is shown in a different way | |
55 | % thus, we do not need to include it in the prettyprint | |
56 | pp(classic,X,error) :- X=top(_), !. | |
57 | % in rodin, we show an error listing all infered units | |
58 | pp(eventb,X,PPOut) :- | |
59 | X=top(List), !, | |
60 | maplist(pp_unit(eventb),List,PPList), | |
61 | ajoin([multiple, '(', PPList, ')'], PPOut). | |
62 | % avl_sets from inside a value term | |
63 | pp(ClassicOrEventB,avl_set(A),PPOut) :- !, | |
64 | avl_domain(A,Dom), maplist(pp(ClassicOrEventB),Dom,PPDom), | |
65 | ajoin_with_sep(PPDom,',',JoinedDom), | |
66 | ajoin(['{',JoinedDom,'}'],PPOut). | |
67 | pp(_ClassicOrEventB,'$setup_constants','SETUP_CONSTANTS') :- !. | |
68 | pp(_ClassicOrEventB,'$initialise_machine','INITIALISATION') :- !. | |
69 | pp(_ClassicOrEventB,X,X) :- atom(X), !. | |
70 | pp(_ClassicOrEventB,X,X) :- number(X), !. | |
71 | pp(ClassicOrEventB,'-->'(Operation,ResultValues),PrettyTransition) :- !, | |
72 | pp(ClassicOrEventB,Operation,PrettyOperation), | |
73 | pp(ClassicOrEventB,ResultValues,PrettyResults), | |
74 | ajoin([PrettyOperation, '-->', PrettyResults],PrettyTransition). | |
75 | pp(ClassicOrEventB,L,Result) :- | |
76 | is_unit_list(L), | |
77 | pp_unit(ClassicOrEventB,L,Result),!. | |
78 | pp(_ClassicOrEventB,[],[]) :- !. | |
79 | pp(ClassicOrEventB,[H|T],[PH|PT]) :- !, | |
80 | pp(ClassicOrEventB,H,PH), | |
81 | pp(ClassicOrEventB,T,PT). | |
82 | pp(ClassicOrEventB,Compound,Pretty) :- | |
83 | Compound =.. [Head|Args], !, | |
84 | pp(ClassicOrEventB,Head,PrettyHead), | |
85 | pp(ClassicOrEventB,Args,PrettyArgs), | |
86 | Pretty =.. [PrettyHead|PrettyArgs]. | |
87 | pp(_ClassicOrEventB,Term,_Pretty) :- | |
88 | !, add_error_fail(units_prettyprint, 'Term not implemented: ', [Term]). | |
89 | ||
90 | pp_unit(ClassicOrEventB,L,Result) :- | |
91 | subseq(L,Com,Sub), | |
92 | unit_alias(Aliased,Sub), !, | |
93 | (Com = [] | |
94 | -> Result = Aliased | |
95 | ; pp_unit(ClassicOrEventB,Com,ComPP), | |
96 | ajoin_with_sep([Aliased,ComPP],' * ',Result)). | |
97 | pp_unit(ClassicOrEventB,[[EtoT,Symbol,EtoS]|T],Result) :- | |
98 | exponentiation_operator(ClassicOrEventB,Exponentiation), | |
99 | (EtoT = 0 | |
100 | -> EtoTPP = '' | |
101 | ; (EtoT = 1 -> EtoTPP = '10*' ; ajoin([10,Exponentiation,EtoT,'*'],EtoTPP))), | |
102 | (EtoS = 1 -> EtoSPP = Symbol ; ajoin([Symbol,Exponentiation,EtoS],EtoSPP)), | |
103 | ajoin([EtoTPP,EtoSPP],FirstUnitPP), | |
104 | (T = [] | |
105 | -> Result = FirstUnitPP | |
106 | ; pp_unit(ClassicOrEventB,T,TPP), | |
107 | ajoin_with_sep([FirstUnitPP,TPP],' * ',Result)). | |
108 | ||
109 | exponentiation_operator(classic,'**'). | |
110 | exponentiation_operator(eventb,'^'). | |
111 | ||
112 | ||
113 | % predicates below should only be called from tcltk | |
114 | pp_fixpoint_result(FixPointState,UnboundInConstraint,PP) :- | |
115 | pp_state(FixPointState,PPFixPointState), | |
116 | evaluate_fixpoint(FixPointState,UnboundInConstraint,Part2), | |
117 | units:iterations(Iterations), | |
118 | evaluate_operation(OperationsResult), | |
119 | ajoin(['Fixpoint reached after ', Iterations,' Iterations\n\nState:\n',PPFixPointState,'\n\n',Part2,'\n',OperationsResult],PP). | |
120 | ||
121 | pp_state([],''). | |
122 | pp_state([bind(Key,Val)|T],Res) :- | |
123 | pp_state(T,PPT), | |
124 | pp(classic,Val,PPVal), | |
125 | ajoin([Key, ' = ', PPVal, '\n', PPT],Res). | |
126 | ||
127 | evaluate_operation(OperationsResult) :- | |
128 | findall(Name, units_interpreter:top_in_parameters(Name), ListOfNames1), | |
129 | findall(Name, units_interpreter:top_in_results(Name), ListOfNames2), | |
130 | (ListOfNames1 = [] | |
131 | -> OperationsResult1 = '' | |
132 | ; ajoin(['Multiple units inferred for parameters of: ', ListOfNames1, '\n\n'], OperationsResult1) | |
133 | ), | |
134 | (ListOfNames2 = [] | |
135 | -> OperationsResult = OperationsResult1 | |
136 | ; ajoin([OperationsResult1,'Multiple units inferred for results of: ', ListOfNames2], OperationsResult) | |
137 | ). | |
138 | ||
139 | evaluate_fixpoint([],_Unbound,''). | |
140 | evaluate_fixpoint([bind(Id,Val)|State],Unbound,AtomOut) :- | |
141 | \+(ground(Val)), member(Id,Unbound), !, | |
142 | ajoin(['No unit inferred for Variable / Constant, but used in constraint: ',Id,'\n'],Out1), | |
143 | evaluate_fixpoint(State,Unbound,SubOut), | |
144 | ajoin([Out1,SubOut],AtomOut). | |
145 | evaluate_fixpoint([bind(Id,Val)|State],Unbound,AtomOut) :- | |
146 | \+(ground(Val)), !, | |
147 | ajoin(['No unit inferred for Variable / Constant: ',Id,'\n'],Out1), | |
148 | evaluate_fixpoint(State,Unbound,SubOut), | |
149 | ajoin([Out1,SubOut],AtomOut). | |
150 | evaluate_fixpoint([bind(Id,Val)|State],Unbound,AtomOut) :- | |
151 | contains_top(Val), !, | |
152 | ajoin(['Multiple units inferred for Variable / Constant: ',Id,'\n'],Out1), | |
153 | evaluate_fixpoint(State,Unbound,SubOut), | |
154 | ajoin([Out1,SubOut],AtomOut). | |
155 | evaluate_fixpoint([bind(_Id,_Val)|State],Unbound,SubOut) :- | |
156 | evaluate_fixpoint(State,Unbound,SubOut). |