1 % (c) 2009-2014 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
6 :- module(fdr_csp_generator, [tcltk_print_states_for_fdr/1,tcltk_print_states_for_spin/1]).
7
8 :- use_module(module_information,[module_info/2]).
9 :- module_info(group,tools).
10 :- module_info(description,'Tools for exporting state space in CSP or Promela format.').
11
12 :- use_module(gensym).
13 :- use_module(library(lists)).
14
15 :- dynamic channel/4.
16 :- dynamic selectsymbol/0.
17 :- dynamic commasymbol/0.
18 :- dynamic written_channel/1.
19
20
21
22 :- use_module(specfile,[animation_mode/1, currently_opened_file/1,csp_with_bz_mode/0]).
23
24 :- use_module(state_space).
25 :- use_module(translate).
26 :- use_module(debug,[time/1]).
27 :- use_module(tools,[print_message/1, ajoin/2]).
28
29
30 tcltk_print_states_for_fdr(F) :-
31 time(fdr_csp_generator:tcltk_print_states_for_fdr2(F)).
32 tcltk_print_states_for_fdr2(F) :-
33 print_message('Saving State Space to FDR/CSP File: '), print_message(F),
34 tell(F),(convert_b_2_csp -> true ; true),told,
35 print_message('Finished').
36 tcltk_print_states_for_spin(F) :-
37 print_message('Saving State Space to SPIN/Promela File: '), print_message(F),
38 tell(F),(convert_b_2_promela -> true ; true),told,
39 print_message('Finished').
40
41
42
43 /* ------------- */
44
45 transition_for_fdr(FromID,Trans,ToID) :- transition(FromID,Trans,ToID),
46 \+ to_be_ignored(Trans).
47
48 to_be_ignored(io([_V1],print,_)). % comes from cspPrint
49
50 /* ------------- */
51
52 convert_b_2_csp :-
53 retractall(current_mode(_)), assert(current_mode(fdr)),
54 convert.
55 convert_b_2_promela :-
56 retractall(current_mode(_)), assert(current_mode(spin)),
57 convert.
58
59 convert :-
60 print_overall_header,
61 (current_mode(fdr) -> true /* no need to print channels */ ; print_channels),
62 gen_process.
63
64 gen_tran:-
65 transition_for_fdr(StateID,TransAsTerm,TID),
66 (channel(TransAsTerm,_,StateID,_) -> fail
67 ; (translate_event(TransAsTerm,Trans),
68 generate_transition_id(TransAsTerm,Trans,FDRTransID),
69 assert(channel(TransAsTerm,FDRTransID,StateID,TID))
70 )
71 ),fail.
72 gen_tran.
73
74 generate_transition_id(TransAsTerm,_,TransID) :-
75 var(TransAsTerm),!,TransID = error_trans_is_var.
76 generate_transition_id(TransAsTerm,_,TransID) :- atomic(TransAsTerm),!,TransID = TransAsTerm.
77 generate_transition_id(TransAsTerm,Transs,TransID) :-
78 functor(TransAsTerm,Func,_),
79 (Func = ('-->')
80 -> arg(1,TransAsTerm,Arg), generate_transition_id(Arg,Transs,TransID)
81 ; ((Func = '$initialise_machine' ; Func = '$setup_constants')
82 -> TransID = Func
83 ; Transs = TransID %char_translate(Transs,TransID)
84 )
85 ).
86
87
88 %char_translate(Sf,ResultS) :-
89 % name(Sf, Sflist),
90 % mysubstitute(123,Sflist,40,SflistR), /* { -> ( */
91 % mysubstitute(125,SflistR,41,SflistRR), /* } -> ) */
92 % %mysubstitute(40,SflistRR,95,SflistRRR),
93 % %mysubstitute(41,SflistRRR,95,SflistRRRR),
94 % %%mysubstitute(44,SflistRR,95,SflistRRRRR),
95 % name(ResultS,SflistRR).
96 %
97 %
98 %mysubstitute(X,L,Y,Res) :- sub(L,X,Y,Res). /* for Sicstus 4 */
99 %sub([],_,_,[]).
100 %sub([H|T],X,Y,[SH|ST]) :-
101 % (H=X -> SH=Y ; SH=H),
102 % sub(T,X,Y,ST).
103
104
105 write_tran:-
106 (animation_mode(cspm) -> print('-- ') ; true), /* Comment out if in CSP mode as original CSP will already define channels */
107 print_channel_keyword,
108 channel(_,ID,_,_),
109 (written_channel(ID) -> true ; (
110 assert(written_channel(ID)),
111 print_comma,
112 print(ID))),
113 fail.
114 write_tran:- print_end_of_construct,nl.
115
116 print_comma:-
117 (commasymbol -> print(',') ; assert(commasymbol)).
118
119
120 print_channels :-
121 %time(fdr_csp_generator:gen_tran),
122 gen_tran,
123 retractall(commasymbol),
124 retractall(written_channel(_)),
125 write_tran,nl.
126
127 gen_process :- print_transition_header,fail.
128 gen_process :-
129 visited_expression_id(NodeIDs),
130 print_process_declaration_header(NodeIDs),
131 retractall(selectsymbol),
132 (transition_for_fdr(NodeIDs,_,_) -> process_detail(NodeIDs)
133 ; (not_all_transitions_added(NodeIDs)
134 -> print_open_detail(NodeIDs) ; print_stop_detail(NodeIDs))
135 ),
136 print_process_declaration_footer(NodeIDs), fail.
137 gen_process:- print_transition_footer.
138
139 :- dynamic tau_found/0, non_tau_found/0.
140 assert_tau_found_fail :- \+ tau_found, assert(tau_found), fail.
141 %assert_non_tau_found :- non_tau_found -> true ; assert(non_tau_found).
142
143 process_detail(Node1) :-
144 retractall(tau_found), retractall(non_tau_found),
145 %non_tau_transition_exists(Node1),!,
146 process_non_tau_detail(Node1),!,
147 (tau_found % tau_transition(Node1,_,_)
148 -> ( print(' [> '), process_tau_instructions(Node1))
149 ; true),
150 nl.
151 process_detail(Node1) :- \+ non_tau_found,
152 (tau_found % tau_transition(Node1,_,_)
153 -> ( process_tau_instructions(Node1))
154 ; print(' STOP ')
155 ),
156 nl.
157
158 process_non_tau_detail(Node1) :-
159 transition_for_fdr(Node1,TransAsTerm,Node2),
160 (is_tau(TransAsTerm) -> assert_tau_found_fail
161 ; (non_tau_found -> true ; (print(' ( '),assert(non_tau_found) ))),
162 print_detail(TransAsTerm,Node1,Node2),nl,fail.
163 process_non_tau_detail(_) :- non_tau_found,
164 (selectsymbol -> (print(' ) '),retract(selectsymbol)) ; print(' STOP ) ') ).
165
166 %non_tau_transition_exists(Node1) :-
167 % transition_for_fdr(Node1,TransAsTerm,_Node2),\+ is_tau(TransAsTerm).
168
169 tau_transition(Node1,TransAsTerm,Node2) :-
170 transition_for_fdr(Node1,TransAsTerm,Node2),is_tau(TransAsTerm).
171
172 is_tau(tau(_)).
173 is_tau(start_cspm_MAIN).
174
175 process_tau_instructions(Node1) :- print(' ( '),
176 tau_transition(Node1,Trans,Node2),
177 print_tau_detail(Trans,Node2),nl,fail.
178 process_tau_instructions(_) :- print(' ) ').
179
180
181 print_detail(TransAsTerm,_Node1,Node2):-
182 fdr_translate_event(TransAsTerm,TransAsString),
183 (selectsymbol -> print(' [] '); (current_mode(fdr) -> assert(selectsymbol) ; true)),
184 print_single_transition(TransAsString,Node2).
185
186 print_tau_detail(Trans,Node2):-
187 (selectsymbol -> print(' |~| '); (current_mode(fdr) -> assert(selectsymbol) ; true)),
188 print_single_tau_transition(Trans,Node2).
189
190 fdr_translate_event(Transition,String) :-
191 csp_with_bz_mode,!,
192 fdr_translate_event2(Transition,String).
193 fdr_translate_event(Transition,String) :-
194 translate_event(Transition,String).
195
196 fdr_translate_event2(io(Values,Channel,_Span),String) :- !,
197 translate_event(io(Values,Channel),String). % omit "CSP: ..."
198 fdr_translate_event2('-->'(Operation,OutputValues),String) :- !,
199 Operation =.. [Channel|InputValues],
200 append(InputValues,OutputValues,Values),
201 fdr_translate_operation(Channel,Values,String).
202 fdr_translate_event2(Event,String) :-
203 is_csp_event(Event),!,translate_event(Event,String).
204 fdr_translate_event2(Operation,String) :-
205 Operation =.. [Channel|Values],
206 fdr_translate_operation(Channel,Values,String).
207
208 fdr_translate_operation(Name,Values,String) :-
209 maplist(translate_bvalue,Values,ValueStrings),
210 inject_dots([Name|ValueStrings],Strings),
211 ajoin(Strings,String).
212
213 inject_dots([],[]).
214 inject_dots([E],[E]) :- !.
215 inject_dots([H|T],[H,'.'|NT]) :-
216 inject_dots(T,NT).
217
218
219
220 is_csp_event(start_cspm(_)).
221 is_csp_event(tick(_)).
222 is_csp_event(tau(_)).
223 is_csp_event(io(_,_,_)).
224 is_csp_event(io(_,_)).
225
226
227
228 /* Language dependent stuff */
229 :- dynamic current_mode/1.
230
231 current_mode(fdr).
232
233 print_overall_header :- retractall(prob__open__node_generated),
234 current_mode(fdr),!,
235 print('-- ProB State Space Encoded for FDR in CSP'),nl,
236 currently_opened_file(F),
237 (animation_mode(cspm) -> (nl, print('include "'),
238 print(F),print('"'),nl,nl,
239 print('assert MAIN [FD= Nroot'),nl,
240 print('assert Nroot [FD= MAIN'),nl,nl)
241 ; (print('-- Original file: '), print(F))
242 ),
243 print('--'),nl.
244 print_overall_header :- print('/* ProB State Space Encoded for Spin in Promela */'),nl,
245 currently_opened_file(F),
246 print('/* Original file: '), print(F), print(' */'),nl.
247
248 print_channel_keyword :- current_mode(fdr),!,
249 print('channel ').
250 print_channel_keyword :- print('chan ').
251
252 print_end_of_construct :- current_mode(fdr),!,nl.
253 print_end_of_construct :- print(';'),nl.
254
255 print_transition_header :- current_mode(fdr),!,nl.
256 print_transition_header :- nl, print('active proctype root()'),nl,print('{'),nl.
257
258 :- dynamic prob__open__node_generated/0.
259 print_transition_footer :- current_mode(fdr),!,
260 (prob__open__node_generated
261 -> (print_channel_keyword, print('prob__open__node'),print_end_of_construct
262 )
263 ; true
264 ),
265 print('-- end of ProB Encoding'),nl.
266 print_transition_footer :- print('}'),nl, print('/* end of ProB Encoding */'),nl.
267
268 print_process_declaration_header(ID) :- current_mode(fdr),!,
269 print('N'),print(ID), print(' = ').
270 print_process_declaration_header(ID) :-
271 print('N'),print(ID), print(':'),nl,
272 print(' if'),nl.
273
274 print_process_declaration_footer(_) :- current_mode(fdr),!,nl.
275 print_process_declaration_footer(_) :- print(' fi;'),nl.
276
277
278 print_single_transition(TransName,ToNodeID) :- current_mode(fdr),!,
279 ((TransName = tick(_) ; TransName=tick)
280 -> (print('SKIP {- N'),print(ToNodeID),print(' ( == STOP) -}'))
281 ; ((TransName = i(_) ; TransName=i)
282 -> (print('(STOP /\\ N'),print(ToNodeID), print(')') )
283 ; (print(TransName),print('->'),print('N'),print(ToNodeID))
284 )
285 ).
286 print_single_transition(TransName,ToNodeID) :- !,print(' :: printf("'),
287 print(TransName),print('\\n") -> goto '), print('N'),print(ToNodeID).
288 print_single_transition(TransName,ToNodeID) :- print(' :: '),
289 print(TransName),print('-> goto '), print('N'),print(ToNodeID).
290
291
292
293 print_single_tau_transition(TransName,ToNodeID) :- current_mode(fdr),!,
294 print(' {- '),print(TransName),print('->'), print(' -} N'),print(ToNodeID).
295 print_single_tau_transition(TransName,ToNodeID) :- !,print(' :: printf("'),
296 print(TransName),print('\\n") -> goto '), print('N'),print(ToNodeID).
297 print_single_tau_transition(TransName,ToNodeID) :- print(' :: '),
298 print(TransName),print('-> goto '), print('N'),print(ToNodeID).
299
300
301 print_stop_detail(_) :- current_mode(fdr),!,print('STOP'),nl.
302 print_stop_detail(NodeIDs) :- print_single_transition(prob__deadlock,NodeIDs).
303
304 print_open_detail(_NodeIDs) :- current_mode(fdr),!,print('prob__open__node -> STOP'),nl,
305 assert(prob__open__node_generated).
306 print_open_detail(NodeIDs) :- print_single_transition(prob__open__node,NodeIDs).
307
308 /* --------------------------- */
309