@@ -16,22 +16,160 @@ type agent = (string * port list)
16
16
17
17
type mixture = agent list
18
18
19
+ type lnk_or_int = INT of string
20
+ | LNK of link
21
+
22
+ type q = int * string * lnk_or_int
23
+
24
+ type quarks = Tested of q list
25
+ | TestedMod of (q * q) list
26
+ | Modified of q list
27
+
19
28
type rule = {
20
29
lhs : mixture ;
21
- bidirectional :bool ;
30
+ bidirectional : bool ;
22
31
rhs : mixture ;
32
+ prefix_map : quarks list ;
23
33
}
24
34
type t = INIT of mixture
25
35
| OBS of string * mixture
26
36
| RULE of string * rule
27
37
38
+
39
+ let add_free_to_port_lnk plinks = match plinks with
40
+ | [] -> [FREE ]
41
+ | ls -> ls
42
+
43
+ let add_free_to_mix mix =
44
+ List. map
45
+ (fun (n ,pl ) ->
46
+ let pl' =
47
+ List. map
48
+ (fun p ->
49
+ let p_lnks= add_free_to_port_lnk p.port_lnk in
50
+ {port_nme= p.port_nme;port_int= p.port_int; port_lnk= p_lnks}) pl in
51
+ (n,pl')) mix
52
+
53
+ let split_ports_quarks count port =
54
+ let quark_int = match port.port_int with
55
+ | [] -> []
56
+ | s ::_ -> [(count,port.port_nme,(INT s))] in
57
+ match port.port_lnk with
58
+ | [] -> []
59
+ | l ::_ -> (count,port.port_nme,(LNK l))::quark_int
60
+
61
+ let create_quarks mixture count =
62
+ List. fold_left
63
+ (fun (qs ,agent_names ,count ) (name ,plist ) ->
64
+ let qs' =
65
+ List. fold_left
66
+ (fun acc port -> (split_ports_quarks count port)@ acc) [] plist in
67
+ (qs'@ qs,(name,count)::agent_names,count+ 1 ))
68
+ ([] ,[] ,count) mixture
69
+
70
+ let create_rhs_quarks agent_names mixture =
71
+ let rec aux qs mixt count ag_nm =
72
+ match mixt with
73
+ | (name ,plist )::mixt' ->
74
+ if (List. mem (name,count) ag_nm) then
75
+ let qs' =
76
+ List. fold_left
77
+ (fun acc port -> (split_ports_quarks count port)@ acc) [] plist in
78
+ aux (qs'@ qs) mixt' (count+ 1 ) ag_nm
79
+ else
80
+ let (qs',ag_nm',_) = create_quarks mixt' (List. length ag_nm) in
81
+ (qs'@ qs, ag_nm'@ ag_nm)
82
+ | [] -> (qs, [] ) in
83
+ aux [] mixture 0 agent_names
84
+
85
+ let match_il il il' = match (il,il') with
86
+ | (INT _ ,INT _ ) | (LNK _ ,LNK _ ) -> true
87
+ | _ -> false
88
+
89
+ let remove_quark (n ,p ,il ) ls =
90
+ List. filter
91
+ (fun (n' ,p' ,il' ) ->
92
+ (not ((n= n')&& (String. equal p p')&& (match_il il il')))) ls
93
+
94
+ let partition_quarks lhs_quarks rhs_quarks =
95
+ let find (n ,p ,il ) rhs =
96
+ List. find (fun (n' ,p' ,il' ) ->
97
+ (n= n')&& (String. equal p p')&& (match_il il il')) rhs in
98
+ let (tested,tested_mod,rhs)=
99
+ List. fold_left
100
+ (fun (tested ,tested_mod ,rhs ) (n ,p ,il ) ->
101
+ if (List. mem (n,p,il) rhs_quarks) then
102
+ (((n,p,il)::tested),tested_mod,(remove_quark (n,p,il) rhs))
103
+ else
104
+ let (n',p',il') =
105
+ (try (find (n,p,il) rhs)
106
+ with _ ->
107
+ (raise
108
+ (ExceptionDefn. Syntax_Error
109
+ (" agent does not have the same ports in lhs and rhs" )))) in
110
+ (tested,((n,p,il),(n',p',il'))::tested_mod,
111
+ (remove_quark (n,p,il) rhs)))
112
+ ([] ,[] ,rhs_quarks) lhs_quarks in
113
+ let () =
114
+ List. iter (fun (ag ,_ ,_ ) ->
115
+ List. iter
116
+ (fun (ag' ,_ ,_ ) ->
117
+ if (ag= ag') then
118
+ (raise
119
+ (ExceptionDefn. Syntax_Error
120
+ (" agent does not have the same ports
121
+ in lhs and rhs" )))) rhs)
122
+ tested in
123
+ (tested,tested_mod,rhs)
124
+
125
+ let create_prefix_map lhs rhs =
126
+ let (lhs_quarks,lhs_agent_nm,_) = create_quarks lhs 0 in
127
+ let (rhs_quarks,rhs_agent_nm) = create_rhs_quarks lhs_agent_nm rhs in
128
+ let (t_quarks,tm_quarks,m_quarks) =
129
+ partition_quarks lhs_quarks rhs_quarks in
130
+ [Tested t_quarks; TestedMod tm_quarks; Modified m_quarks]
131
+
132
+ let clean_rules = function
133
+ | INIT mix -> INIT (add_free_to_mix mix)
134
+ | OBS (name ,mix ) -> OBS (name,add_free_to_mix mix)
135
+ | RULE (name ,r ) ->
136
+ let () = if (r.bidirectional) then
137
+ (raise (ExceptionDefn. Not_Supported
138
+ (" bidirectional rules not supported" ))) in
139
+ let lhs = add_free_to_mix r.lhs in
140
+ let rhs = add_free_to_mix r.rhs in
141
+ let r' = {lhs; bidirectional= r.bidirectional;rhs;
142
+ prefix_map = (create_prefix_map lhs rhs)} in
143
+ RULE (name,r')
144
+
28
145
let print_link = function
29
146
| LNK_VALUE i -> Format. printf " !%d" i
30
- | FREE -> ()
147
+ | FREE -> Format. printf " free "
31
148
| LNK_ANY -> Format. printf " !_"
32
149
| LNK_SOME -> Format. printf " !_"
33
150
| LNK_TYPE (i ,a ) -> Format. printf " !%s.%s" i a
34
151
152
+ let print_quarks qs =
153
+ let print_q (n ,p ,il ) =
154
+ Format. printf " (%d,%s," n p;
155
+ (match il with
156
+ INT i -> Format. printf " int=%s " i
157
+ | LNK lnk ->
158
+ Format. printf " lnk= " ; print_link lnk);
159
+ Format. printf " )" in
160
+ let print_qlist qlist =
161
+ List. iter (fun q -> print_q q) qlist in
162
+ match qs with
163
+ | Tested qlist ->
164
+ Format. printf " \n Tested: " ; print_qlist qlist
165
+ | Modified qlist ->
166
+ Format. printf " \n Modified: " ; print_qlist qlist
167
+ | TestedMod qqlist ->
168
+ Format. printf " \n TestedMod " ;
169
+ List. iter (fun (q1 ,q2 ) ->
170
+ Format. printf" [before = " ;print_q q1;Format. printf " ] " ;
171
+ Format. printf" [after = " ;print_q q2;Format. printf " ] " ) qqlist
172
+
35
173
let print_port p =
36
174
Format. printf " %s~[" p.port_nme;
37
175
List. iter (fun intern -> Format. printf " %s " intern;) p.port_int;
@@ -47,15 +185,16 @@ let print_rule r =
47
185
List. iter (fun a -> print_agent a) r.lhs;
48
186
if (r.bidirectional) then Format. printf " <-> "
49
187
else Format. printf " -> " ;
50
- List. iter (fun a -> print_agent a) r.rhs
188
+ List. iter (fun a -> print_agent a) r.rhs;
189
+ List. iter (fun quarks -> print_quarks quarks) r.prefix_map
51
190
52
191
let print = function
53
192
| INIT mix -> Format. printf " \n init " ; List. iter (fun a -> print_agent a) mix
54
193
| OBS (name ,mix ) -> Format. printf " \n obs '%s' " name;
55
194
List. iter (fun a -> print_agent a) mix
56
195
| RULE (name ,r ) -> Format. printf " \n rule '%s' " name; print_rule r
57
196
58
- let empty_rule = {lhs = [] ;rhs= [] ;bidirectional= false }
197
+ let empty_rule = {lhs = [] ;rhs= [] ;bidirectional= false ;prefix_map = [] }
59
198
60
199
let empty = RULE (" empty" ,empty_rule)
61
200
0 commit comments