Joining Constraint Satisfaction Problems and Configurable CAD Product Models: A Step-by-Step Implementation Guide
Abstract
:1. Introduction
2. Theoretical Background
3. Modeling Task
4. Specification of the Information System
5. Building the CSP
5.1. Domain and Constraint Lists
5.2. Creating Domains and the Constraint List
5.3. User Interface
5.4. Constraint Handling
5.4.1. Queueing
5.4.2. Solver and Output of the Solution Set
5.5. Resetting a Selection
5.6. Extending the Example from 8 to 10 Domains
- Sub reset: New domains and control elements integrated according to Appendix A, row 26, 31, 40, 44, 48 and 52.
- Sub generate domains: New loop according to Appendix A, row 96 to 98 and row 130 to 132.
- Sub get_constraints: New translations like in Appendix A, row 160/161, 168/169, 180/181, 188/189, 208/209, 214/215, 227/228, 235/236.
- Sub update_listboxes: Introduction of slots5 and bricks5 according to Appendix A, row 277–282 and 300–304.
- Sub constraint_relax: Introduction of slots5 and bricks5 according to Appendix A, row 375–387 and 426–434.
- cmd_relax_1_5: Code added according to Appendix B, row 8–16.
- lbx_slots5_doubleclick: Code added according to Appendix B, row 45–69.
6. Addressing the CAD Assembly
7. Discussion and Conclusions
Funding
Institutional Review Board Statement
Informed Consent Statement
Data Availability Statement
Conflicts of Interest
Appendix A. Code for Module Main
Row | Code |
---|---|
1 | ‘For Dictionary Use activate: |
2 | ‘Extras -> References -> Microsoft Scripting Runtime |
3 | |
4 | ‘Generate Dictionaries for all Components |
5 | Public dict_Slots1 As New Dictionary, dict_Slots2 As New Dictionary |
6 | Public dict_Slots3 As New Dictionary, dict_Slots4 As New Dictionary |
7 | Public dict_SlotsORI As New Dictionary |
8 | Public dict_Bricks1 As New Dictionary, dict_Bricks2 As New Dictionary |
9 | Public dict_Bricks3 As New Dictionary, dict_Bricks4 As New Dictionary |
10 | Public dict_BricksORI As New Dictionary |
11 | |
12 | ‘Generate Constraint Handling |
13 | Public dict_ConList As New Dictionary |
14 | Public dict_ConQue As New Dictionary |
15 | |
16 | ‘Internal Selection Working Memory |
17 | Public strSlot1, strSlot2, strSlot3, strSlot4 As String |
18 | Public strBrick1, strBrick2, strBrick3, strBrick4 As String |
19 | |
20 | ‘Global Counter |
21 | Public count_Slots As Integer |
22 | |
23 | |
24 | Sub reset() |
25 | ‘Clear all Dicitonaries |
26 | dict_Slots1.RemoveAll |
27 | dict_Slots2.RemoveAll |
28 | dict_Slots3.RemoveAll |
29 | dict_Slots4.RemoveAll |
30 | dict_SlotsORI.RemoveAll |
31 | dict_Bricks1.RemoveAll |
32 | dict_Bricks2.RemoveAll |
33 | dict_Bricks3.RemoveAll |
34 | dict_Bricks4.RemoveAll |
35 | dict_BricksORI.RemoveAll |
36 | dict_ConQue.RemoveAll |
37 | dict_ConList.RemoveAll |
38 | |
39 | ‘Clear User Interface |
40 | UserForm1.lbx_Slots1.Clear |
41 | UserForm1.lbx_Slots2.Clear |
42 | UserForm1.lbx_Slots3.Clear |
43 | UserForm1.lbx_Slots4.Clear |
44 | UserForm1.lbx_Bricks1.Clear |
45 | UserForm1.lbx_Bricks2.Clear |
46 | UserForm1.lbx_Bricks3.Clear |
47 | UserForm1.lbx_Bricks4.Clear |
48 | UserForm1.lbl_Slots1.Caption = ““ |
49 | UserForm1.lbl_Slots2.Caption = ““ |
50 | UserForm1.lbl_Slots3.Caption = ““ |
51 | UserForm1.lbl_Slots4.Caption = ““ |
52 | UserForm1.lbl_Bricks1.Caption = ““ |
53 | UserForm1.lbl_Bricks2.Caption = ““ |
54 | UserForm1.lbl_Bricks3.Caption = ““ |
55 | UserForm1.lbl_Bricks4.Caption = ““ |
56 | |
57 | ‘Reset Global Counter |
58 | count_Slots = 0 |
59 | End Sub |
60 | |
61 | |
62 | Sub read_inventory() |
63 | Dim ExcWB As Excel.Workbook |
64 | ‘------------------------------------------------------- |
65 | ‘ADJUST PATH TO LOCAL PATH OF THE REPOSITORY FILE BELOW! |
66 | ‘------------------------------------------------------- |
67 | Set ExcWB = Workbooks.Open(“…\Inventory_List.xlsx”) |
68 | |
69 | ‘Call creating subs |
70 | generate_domains ExcWB.Worksheets(“Slots”) |
71 | generate_Brickss ExcWB.Worksheets(“Bricks”) |
72 | get_constraints ExcWB.Worksheets(“_CONSTRAINTS_”) |
73 | |
74 | ‘Close Workbook |
75 | ExcWB.Close |
76 | End Sub |
77 | |
78 | |
79 | Sub generate_domains(ByVal ExcWS As Excel.WorkSheet) |
80 | Dim iRow As Integer |
81 | Dim key As Variant |
82 | |
83 | ‘Set Start for reading in second row |
84 | iRow = 2 |
85 | ‘Get Slot Domain Master |
86 | Do Until ExcWS.Cells(iRow, 1).Value = ““ |
87 | ArticleID = ExcWS.Cells(iRow, 1).Value |
88 | Set oPart1 = New iComponent_Slots |
89 | oPart1.Slots_Colour = ExcWS.Cells(iRow, 2).Value |
90 | oPart1.Slots_Shape = ExcWS.Cells(iRow, 3).Value |
91 | dict_SlotsORI.Add ArticleID, oPart1 |
92 | iRow = iRow + 1 |
93 | Loop |
94 | |
95 | ‘Distribute Master to all 4 Slot Domains |
96 | For Each key In dict_SlotsORI |
97 | dict_Slots1.Add (key), dict_SlotsORI(key) |
98 | Next |
99 | For Each key In dict_SlotsORI |
100 | dict_Slots2.Add (key), dict_SlotsORI(key) |
101 | Next |
102 | For Each key In dict_SlotsORI |
103 | dict_Slots3.Add (key), dict_SlotsORI(key) |
104 | Next |
105 | For Each key In dict_SlotsORI |
106 | dict_Slots4.Add (key), dict_SlotsORI(key) |
107 | Next |
108 | |
109 | End Sub |
110 | |
111 | |
112 | Sub generate_Brickss(ByVal ExcWS As Excel.WorkSheet) |
113 | Dim iRow As Integer |
114 | Dim key As Variant |
115 | |
116 | ‘Set Start for reading in second row |
117 | iRow = 2 |
118 | ‘Get Brick Domain Master |
119 | Do Until ExcWS.Cells(iRow, 1).Value = ““ |
120 | ArticleID = ExcWS.Cells(iRow, 1).Value |
121 | Set oPart1 = New iComponent_Bricks |
122 | oPart1.Bricks_Colour = ExcWS.Cells(iRow, 2).Value |
123 | oPart1.Bricks_Shape = ExcWS.Cells(iRow, 3).Value |
124 | oPart1.Bricks_Infill = ExcWS.Cells(iRow, 4).Value |
125 | dict_BricksORI.Add ArticleID, oPart1 |
126 | iRow = iRow + 1 |
127 | Loop |
128 | |
129 | ‘Distribute Master to all 4 Brick Domains |
130 | For Each key In dict_BricksORI |
131 | dict_Bricks1.Add (key), dict_BricksORI(key) |
132 | Next |
133 | For Each key In dict_BricksORI |
134 | dict_Bricks2.Add (key), dict_BricksORI(key) |
135 | Next |
136 | For Each key In dict_BricksORI |
137 | dict_Bricks3.Add (key), dict_BricksORI(key) |
138 | Next |
139 | For Each key In dict_BricksORI |
140 | dict_Bricks4.Add (key), dict_BricksORI(key) |
141 | Next |
142 | |
143 | End Sub |
144 | |
145 | Sub get_constraints(ByVal ExcWS As Excel.WorkSheet) |
146 | Dim ConPa As iConstraint |
147 | ‘Set Start for reading in second row |
148 | iRow = 2 |
149 | KeyID = 1 |
150 | |
151 | ‘Get Constraints from Repository |
152 | Do Until ExcWS.Cells(iRow, 1).Value = ““ |
153 | |
154 | ‘------ EQUALITIES / INEQUALITIES ------ |
155 | If ExcWS.Cells(iRow, 2) = “equal” Or ExcWS.Cells(iRow, 2) = “unequal” Then |
156 | ‘Formalize for Processing in VBA |
157 | Set oConstraint1 = New iConstraint |
158 | ‘Assign Source Domain |
159 | Select Case ExcWS.Cells(iRow, 4) |
160 | Case “Slots1” |
161 | Set oConstraint1.ConArg1 = dict_Slots1 |
162 | Case “Slots2” |
163 | Set oConstraint1.ConArg1 = dict_Slots2 |
164 | Case “Slots3” |
165 | Set oConstraint1.ConArg1 = dict_Slots3 |
166 | Case “Slots4” |
167 | Set oConstraint1.ConArg1 = dict_Slots4 |
168 | Case “Bricks1” |
169 | Set oConstraint1.ConArg1 = dict_Bricks1 |
170 | Case “Bricks2” |
171 | Set oConstraint1.ConArg1 = dict_Bricks2 |
172 | Case “Bricks3” |
173 | Set oConstraint1.ConArg1 = dict_Bricks3 |
174 | Case “Bricks4” |
175 | Set oConstraint1.ConArg1 = dict_Bricks4 |
176 | End Select |
177 | oConstraint1.ConArg1Str = ExcWS.Cells(iRow, 4) |
178 | ‘Assign Target Domain |
179 | Select Case ExcWS.Cells(iRow, 5) |
180 | Case “Slots1” |
181 | Set oConstraint1.ConArg2 = dict_Slots1 |
182 | Case “Slots2” |
183 | Set oConstraint1.ConArg2 = dict_Slots2 |
184 | Case “Slots3” |
185 | Set oConstraint1.ConArg2 = dict_Slots3 |
186 | Case “Slots4” |
187 | Set oConstraint1.ConArg2 = dict_Slots4 |
188 | Case “Bricks1” |
189 | Set oConstraint1.ConArg2 = dict_Bricks1 |
190 | Case “Bricks2” |
191 | Set oConstraint1.ConArg2 = dict_Bricks2 |
192 | Case “Bricks3” |
193 | Set oConstraint1.ConArg2 = dict_Bricks3 |
194 | Case “Bricks4” |
195 | Set oConstraint1.ConArg2 = dict_Bricks4 |
196 | End Select |
197 | oConstraint1.ConArg2Str = ExcWS.Cells(iRow, 5) |
198 | ‘Get Expression |
199 | oConstraint1.ConExpr = ExcWS.Cells(iRow, 2) |
200 | ‘Add to Constraint List |
201 | dict_ConList.Add KeyID, oConstraint1 |
202 | KeyID = KeyID + 1 |
203 | |
204 | ‘If binary get inverse Constraint |
205 | If ExcWS.Cells(iRow, 3) = “TRUE” Then |
206 | Set oConstraint1 = New iConstraint |
207 | Select Case ExcWS.Cells(iRow, 5) |
208 | Case “Slots1” |
209 | Set oConstraint1.ConArg1 = dict_Slots1 |
210 | Case “Slots2” |
211 | Set oConstraint1.ConArg1 = dict_Slots2 |
212 | Case “Slots3” |
213 | Set oConstraint1.ConArg1 = dict_Slots3 |
214 | Case “Slots4” |
215 | Set oConstraint1.ConArg1 = dict_Slots4 |
216 | Case “Bricks1” |
217 | Set oConstraint1.ConArg1 = dict_Bricks1 |
218 | Case “Bricks2” |
219 | Set oConstraint1.ConArg1 = dict_Bricks2 |
220 | Case “Bricks3” |
221 | Set oConstraint1.ConArg1 = dict_Bricks3 |
222 | Case “Bricks4” |
223 | Set oConstraint1.ConArg1 = dict_Bricks4 |
224 | End Select |
225 | oConstraint1.ConArg1Str = ExcWS.Cells(iRow, 5) |
226 | Select Case ExcWS.Cells(iRow, 4) |
227 | Case “Slots1” |
228 | Set oConstraint1.ConArg2 = dict_Slots1 |
229 | Case “Slots2” |
230 | Set oConstraint1.ConArg2 = dict_Slots2 |
231 | Case “Slots3” |
232 | Set oConstraint1.ConArg2 = dict_Slots3 |
233 | Case “Slots4” |
234 | Set oConstraint1.ConArg2 = dict_Slots4 |
235 | Case “Bricks1” |
236 | Set oConstraint1.ConArg2 = dict_Bricks1 |
237 | Case “Bricks2” |
238 | Set oConstraint1.ConArg2 = dict_Bricks2 |
239 | Case “Bricks3” |
240 | Set oConstraint1.ConArg2 = dict_Bricks3 |
241 | Case “Bricks4” |
242 | Set oConstraint1.ConArg2 = dict_Bricks4 |
243 | End Select |
244 | oConstraint1.ConArg2Str = ExcWS.Cells(iRow, 4) |
245 | oConstraint1.ConExpr = ExcWS.Cells(iRow, 2) |
246 | dict_ConList.Add KeyID, oConstraint1 |
247 | KeyID = KeyID + 1 |
248 | End If |
249 | End If |
250 | |
251 | ‘------ OBLIGATIONS ------ |
252 | If ExcWS.Cells(iRow, 2) = “obligation” Then |
253 | Set oConstraint1 = New iConstraint |
254 | ‘Get Arguments |
255 | oConstraint1.ConArg1Str = ExcWS.Cells(iRow, 4) |
256 | oConstraint1.ConArg2Str = ExcWS.Cells(iRow, 5) |
257 | oConstraint1.ConArg3Str = ExcWS.Cells(iRow, 6) |
258 | oConstraint1.ConArg4Str = ExcWS.Cells(iRow, 7) |
259 | ‘Get Get Expression |
260 | oConstraint1.ConExpr = ExcWS.Cells(iRow, 2) |
261 | oConstraint1.ConIndex = ExcWS.Cells(iRow, 1) |
262 | ‘Add to Constraint List |
263 | dict_ConList.Add KeyID, oConstraint1 |
264 | KeyID = KeyID + 1 |
265 | End If |
266 | |
267 | iRow = iRow + 1 |
268 | Loop |
269 | count_Slots = 0 |
270 | |
271 | End Sub |
272 | |
273 | |
274 | Sub update_Listboxes() |
275 | ‘Update Content of the User Interface |
276 | ‘Update Slots |
277 | UserForm1.lbx_Slots1.Clear |
278 | ‘Repopulate Listbox from Domain |
279 | For Each key In dict_Slots1 |
280 | Set oComp = dict_Slots1(key) |
281 | UserForm1.lbx_Slots1.AddItem (oComp.Slots_Colour) |
282 | Next |
283 | UserForm1.lbx_Slots2.Clear |
284 | For Each key In dict_Slots2 |
285 | Set oComp = dict_Slots2(key) |
286 | UserForm1.lbx_Slots2.AddItem (oComp.Slots_Colour) |
287 | Next |
288 | UserForm1.lbx_Slots3.Clear |
289 | For Each key In dict_Slots3 |
290 | Set oComp = dict_Slots3(key) |
291 | UserForm1.lbx_Slots3.AddItem (oComp.Slots_Colour) |
292 | Next |
293 | UserForm1.lbx_Slots4.Clear |
294 | For Each key In dict_Slots4 |
295 | Set oComp = dict_Slots4(key) |
296 | UserForm1.lbx_Slots4.AddItem (oComp.Slots_Colour) |
297 | Next |
298 | |
299 | ‘Update Bricks |
300 | UserForm1.lbx_Bricks1.Clear |
301 | For Each key In dict_Bricks1 |
302 | Set oComp = dict_Bricks1(key) |
303 | UserForm1.lbx_Bricks1.AddItem (oComp.Bricks_Colour & “ | “ & oComp.Bricks_Infill) |
304 | Next |
305 | UserForm1.lbx_Bricks2.Clear |
306 | For Each key In dict_Bricks2 |
307 | Set oComp = dict_Bricks2(key) |
308 | UserForm1.lbx_Bricks2.AddItem (oComp.Bricks_Colour & “ | “ & oComp.Bricks_Infill) |
309 | Next |
310 | UserForm1.lbx_Bricks3.Clear |
311 | For Each key In dict_Bricks3 |
312 | Set oComp = dict_Bricks3(key) |
313 | UserForm1.lbx_Bricks3.AddItem (oComp.Bricks_Colour & “ | “ & oComp.Bricks_Infill) |
314 | Next |
315 | UserForm1.lbx_Bricks4.Clear |
316 | For Each key In dict_Bricks4 |
317 | Set oComp = dict_Bricks4(key) |
318 | UserForm1.lbx_Bricks4.AddItem (oComp.Bricks_Colour & “ | “ & oComp.Bricks_Infill) |
319 | Next |
320 | End Sub |
321 | |
322 | |
323 | Public Sub Constraint_Solver() |
324 | |
325 | Dim key As Variant |
326 | Dim arg1 As Dictionary, arg2 As Dictionary, arg3 As Dictionary, arg4 As Dictionary |
327 | Dim arg1str, arg2str, arg3str, arg4str As String |
328 | Dim ConExpr As String |
329 | Dim oComp As iComponent_Slots |
330 | Dim ConPa As iConstraint |
331 | ‘As long as Queue is not empty |
332 | Do While dict_ConQue.Count <> 0 |
333 | For Each key In dict_ConQue |
334 | ‘Get Arguments from Constraint in Queue |
335 | Set ConPa = dict_ConQue(key) |
336 | Set arg1 = ConPa.ConArg1 |
337 | Set arg2 = ConPa.ConArg2 |
338 | Set arg3 = ConPa.ConArg3 |
339 | Set arg4 = ConPa.ConArg4 |
340 | arg1str = ConPa.ConArg1Str |
341 | arg2str = ConPa.ConArg2Str |
342 | arg3str = ConPa.ConArg3Str |
343 | arg4str = ConPa.ConArg4Str |
344 | ConExpr = ConPa.ConExpr |
345 | ‘Get Expression for processing |
346 | Select Case ConExpr |
347 | ‘Unequality |
348 | Case “unequal” |
349 | ‘Delete Constraint from Queue |
350 | dict_ConQue.Remove (key) |
351 | ‘Call Processing |
352 | Call Del_Equal_Slots(arg1, arg2) |
353 | ‘Equality |
354 | Case “equal” |
355 | dict_ConQue.Remove (key) |
356 | Call Bricks_to_Slots(arg1, arg2) |
357 | ‘Obligatory Assignment |
358 | Case “obligation” |
359 | dict_ConQue.Remove (key) |
360 | Call Set_Obliged_Slots(arg1str, arg2str, arg3str, arg4str) |
361 | Case Else |
362 | dict_ConQue.Remove (key) |
363 | End Select |
364 | Next |
365 | Loop |
366 | ‘Update User Interface |
367 | update_Listboxes |
368 | |
369 | End Sub |
370 | |
371 | |
372 | Sub Constraint_Relax() |
373 | ‘------ Repopulte reset Domain ------ |
374 | ‘Evaluate if Domain is NOT collapsed |
375 | If strSlot1 = ““ Then |
376 | ‘Refresh the domain including reset selection |
377 | ‘for slot |
378 | dict_Slots1.RemoveAll |
379 | For Each key In dict_SlotsORI |
380 | dict_Slots1.Add (key), dict_SlotsORI(key) |
381 | Next |
382 | ‘for brick |
383 | dict_Bricks1.RemoveAll |
384 | For Each key In dict_BricksORI |
385 | dict_Bricks1.Add (key), dict_BricksORI(key) |
386 | Next |
387 | End If |
388 | |
389 | If strSlot2 = ““ Then |
390 | dict_Slots2.RemoveAll |
391 | For Each key In dict_SlotsORI |
392 | dict_Slots2.Add (key), dict_SlotsORI(key) |
393 | Next |
394 | dict_Bricks2.RemoveAll |
395 | For Each key In dict_BricksORI |
396 | dict_Bricks2.Add (key), dict_BricksORI(key) |
397 | Next |
398 | End If |
399 | |
400 | If strSlot3 = ““ Then |
401 | dict_Slots3.RemoveAll |
402 | For Each key In dict_SlotsORI |
403 | dict_Slots3.Add (key), dict_SlotsORI(key) |
404 | Next |
405 | dict_Bricks3.RemoveAll |
406 | For Each key In dict_BricksORI |
407 | dict_Bricks3.Add (key), dict_BricksORI(key) |
408 | Next |
409 | End If |
410 | |
411 | If strSlot4 = ““ Then |
412 | dict_Slots4.RemoveAll |
413 | For Each key In dict_SlotsORI |
414 | dict_Slots4.Add (key), dict_SlotsORI(key) |
415 | Next |
416 | dict_Bricks4.RemoveAll |
417 | For Each key In dict_BricksORI |
418 | dict_Bricks4.Add (key), dict_BricksORI(key) |
419 | Next |
420 | End If |
421 | |
422 | ‘------ Add relevant Constraints to queue ------ |
423 | Dim oConstr As iConstraint |
424 | ‘if the domain is already occupied by a selection |
425 | ‘then add relevant constraints to queue where this is source |
426 | If Not strSlot1 = ““ Then |
427 | Call Un_Constraint(dict_Slots1, strSlot1) |
428 | For Each key In dict_ConList |
429 | Set oConstr = dict_ConList(key) |
430 | If oConstr.ConArg1Str = “Slots1” Then |
431 | dict_ConQue.Add (key), dict_ConList(key) |
432 | End If |
433 | Next |
434 | End If |
435 | |
436 | If Not strSlot2 = ““ Then |
437 | Call Un_Constraint(dict_Slots2, strSlot2) |
438 | For Each key In dict_ConList |
439 | Set oConstr = dict_ConList(key) |
440 | If oConstr.ConArg1Str = “Slots2” Then |
441 | dict_ConQue.Add (key), dict_ConList(key) |
442 | End If |
443 | Next |
444 | End If |
445 | |
446 | If Not strSlot3 = ““ Then |
447 | Call Un_Constraint(dict_Slots3, strSlot3) |
448 | For Each key In dict_ConList |
449 | Set oConstr = dict_ConList(key) |
450 | If oConstr.ConArg1Str = “Slots3” Then |
451 | dict_ConQue.Add (key), dict_ConList(key) |
452 | End If |
453 | Next |
454 | End If |
455 | |
456 | If Not strSlot4 = ““ Then |
457 | Call Un_Constraint(dict_Slots4, strSlot4) |
458 | For Each key In dict_ConList |
459 | Set oConstr = dict_ConList(key) |
460 | If oConstr.ConArg1Str = “Slots4” Then |
461 | dict_ConQue.Add (key), dict_ConList(key) |
462 | End If |
463 | Next |
464 | End If |
465 | |
466 | ‘Start Solver |
467 | Constraint_Solver |
468 | End Sub |
469 | |
470 | |
471 | Sub Un_Constraint(ByRef arg1 As Dictionary, ByVal ConVal As String) |
472 | ‘Collapses Domain according to node consistency |
473 | Dim key As Variant |
474 | Dim oComp As iComponent_Slots |
475 | For Each key In arg1 |
476 | Set oComp = arg1(key) |
477 | If Not oComp.Slots_Colour = ConVal Then |
478 | arg1.Remove (key) |
479 | End If |
480 | Next |
481 | End Sub |
482 | |
483 | |
484 | Sub Del_Equal_Slots(ByRef arg1 As Dictionary, ByRef arg2 As Dictionary) |
485 | ‘Elimitates values equal to the reference domain |
486 | Dim key1 As Variant, key2 As Variant |
487 | Dim oComp1 As iComponent_Slots, oComp2 As iComponent_Slots |
488 | For Each key1 In arg1 |
489 | Set oComp1 = arg1(key1) |
490 | For Each key2 In arg2 |
491 | Set oComp2 = arg2(key2) |
492 | If oComp1.Slots_Colour = oComp2.Slots_Colour Then |
493 | arg2.Remove (key2) |
494 | End If |
495 | Next |
496 | Next |
497 | |
498 | End Sub |
499 | |
500 | |
501 | Sub Bricks_to_Slots(ByRef arg1 As Dictionary, ByRef arg2 As Dictionary) |
502 | ‘Elimitates values unequal to the reference domain |
503 | Dim key1 As Variant, key2 As Variant |
504 | Dim oComp1 As iComponent_Slots |
505 | Dim oComp2 As iComponent_Bricks |
506 | For Each key1 In arg1 |
507 | Set oComp1 = arg1(key1) |
508 | For Each key2 In arg2 |
509 | Set oComp2 = arg2(key2) |
510 | If Not oComp1.Slots_Colour = oComp2.Bricks_Colour Then |
511 | arg2.Remove (key2) |
512 | End If |
513 | Next |
514 | Next |
515 | |
516 | End Sub |
517 | |
518 | Sub Set_Obliged_Slots(ByVal arg1str As String, ByVal arg2str As String, _ |
519 | ByVal arg3str As String, ByVal arg4str As String) |
520 | |
521 | ‘Assigns missing value from template |
522 | |
523 | Dim key1, key2, key3, key4 As Variant |
524 | Dim KeyA, KeyB As Variant |
525 | Dim oComp1 As iComponent_Slots, oComp2 As iComponent_Slots, oComp3 As _ |
526 | iComponent_Slots, oComp4 As iComponent_Slots, oCompA As iComponent_Slots |
527 | |
528 | Dim dict_comp As New Dictionary |
529 | Dim dict_set As New Dictionary |
530 | |
531 | ‘establish comparative dictionary from constraint arguments |
532 | ‘if this domain has an assigned value write it to the comparative dictionary |
533 | If dict_Slots1.Count = 1 Then |
534 | For Each key1 In dict_Slots1 |
535 | Set oComp1 = dict_Slots1(key1) |
536 | ‘get colour independently from sequence or position |
537 | If oComp1.Slots_Colour = arg1str Or oComp1.Slots_Colour = arg2str Or _ |
538 | oComp1.Slots_Colour = arg3str Or oComp1.Slots_Colour = arg4str Then |
539 | dict_comp.Add (key1), dict_Slots1(key1) |
540 | End If |
541 | Next |
542 | End If |
543 | If dict_Slots2.Count = 1 Then |
544 | For Each key2 In dict_Slots2 |
545 | Set oComp2 = dict_Slots2(key2) |
546 | If oComp2.Slots_Colour = arg1str Or oComp2.Slots_Colour = arg2str Or _ |
547 | oComp2.Slots_Colour = arg3str Or oComp2.Slots_Colour = arg4str Then |
548 | dict_comp.Add (key2), dict_Slots2(key2) |
549 | End If |
550 | Next |
551 | End If |
552 | If dict_Slots3.Count = 1 Then |
553 | For Each key3 In dict_Slots3 |
554 | Set oComp3 = dict_Slots3(key3) |
555 | If oComp3.Slots_Colour = arg1str Or oComp3.Slots_Colour = arg2str Or _ |
556 | oComp3.Slots_Colour = arg3str Or oComp3.Slots_Colour = arg4str Then |
557 | dict_comp.Add (key3), dict_Slots3(key3) |
558 | End If |
559 | Next |
560 | End If |
561 | If dict_Slots4.Count = 1 Then |
562 | For Each key4 In dict_Slots4 |
563 | Set oComp4 = dict_Slots4(key4) |
564 | If oComp4.Slots_Colour = arg1str Or oComp4.Slots_Colour = arg2str Or _ |
565 | oComp4.Slots_Colour = arg3str Or oComp4.Slots_Colour = arg4str Then |
566 | dict_comp.Add (key4), dict_Slots4(key4) |
567 | End If |
568 | Next |
569 | End If |
570 | |
571 | ‘check if three slots have been assigned |
572 | If dict_comp.Count = 3 Then |
573 | ‘establish control dictionary for value retrieval |
574 | For Each key In dict_SlotsORI |
575 | Set oCompA = dict_SlotsORI(key) |
576 | If oCompA.Slots_Colour = arg1str Or oCompA.Slots_Colour = arg2str Or _ |
577 | oCompA.Slots_Colour = arg3str Or oCompA.Slots_Colour = arg4str Then |
578 | dict_set.Add (key), dict_SlotsORI(key) |
579 | End If |
580 | Next |
581 | |
582 | ‘identify missing assignment |
583 | For Each KeyA In dict_comp |
584 | dict_set.Remove (KeyA) |
585 | Next |
586 | |
587 | ‘set assignment |
588 | For Each KeyA In dict_set |
589 | Set oCompA = dict_set(KeyA) |
590 | ‘if slot one is the open one then assign last value here and collapse |
591 | If Not dict_Slots1.Count = 1 Then |
592 | For Each key1 In dict_Slots1 |
593 | Set oComp1 = dict_Slots1(key1) |
594 | If Not oComp1.Slots_Colour = oCompA.Slots_Colour Then |
595 | dict_Slots1.Remove (key1) |
596 | End If |
597 | Next |
598 | End If |
599 | If Not dict_Slots2.Count = 1 Then |
600 | For Each key2 In dict_Slots2 |
601 | Set oComp2 = dict_Slots2(key2) |
602 | If Not oComp2.Slots_Colour = oCompA.Slots_Colour Then |
603 | dict_Slots2.Remove (key2) |
604 | End If |
605 | Next |
606 | End If |
607 | If Not dict_Slots3.Count = 1 Then |
608 | For Each key3 In dict_Slots3 |
609 | Set oComp3 = dict_Slots3(key3) |
610 | If Not oComp3.Slots_Colour = oCompA.Slots_Colour Then |
611 | dict_Slots3.Remove (key3) |
612 | End If |
613 | Next |
614 | End If |
615 | If Not dict_Slots4.Count = 1 Then |
616 | For Each key4 In dict_Slots4 |
617 | Set oComp4 = dict_Slots4(key4) |
618 | If Not oComp4.Slots_Colour = oCompA.Slots_Colour Then |
619 | dict_Slots4.Remove (key4) |
620 | End If |
621 | Next |
622 | End If |
623 | Next |
624 | End If |
625 | End Sub |
Appendix B. Code for Userform1
Row | Code |
---|---|
1 | Private Sub cmd_gen_domains_Click() |
2 | ‘Generates the Domains from the Excel Repository and inits User Interface |
3 | Main.reset |
4 | Main.read_inventory |
5 | Main.update_Listboxes |
6 | End Sub |
7 | |
8 | Private Sub cmd_relax1_1_Click() |
9 | ‘Reset Label in User Interface and Internal Selection Working Memory |
10 | lbl_Slots1.Caption = ““ |
11 | strSlot1 = ““ |
12 | ‘decrease global counter by one |
13 | count_Slots = count_Slots − 1 |
14 | ‘Refreshopen Domains |
15 | Main.Constraint_Relax |
16 | End Sub |
17 | |
18 | Private Sub cmd_relax1_2_Click() |
19 | lbl_Slots2.Caption = ““ |
20 | strSlot2 = ““ |
21 | count_Slots = count_Slots − 1 |
22 | Main.Constraint_Relax |
23 | End Sub |
24 | |
25 | Private Sub cmd_relax1_3_Click() |
26 | lbl_Slots3.Caption = ““ |
27 | strSlot3 = ““ |
28 | count_Slots = count_Slots − 1 |
29 | Main.Constraint_Relax |
30 | End Sub |
31 | |
32 | Private Sub cmd_relax1_4_Click() |
33 | lbl_Slots4.Caption = ““ |
34 | strSlot4 = ““ |
35 | count_Slots = count_Slots − 1 |
36 | Main.Constraint_Relax |
37 | End Sub |
38 | |
39 | Private Sub cmd_reset_Click() |
40 | ‘Empty Domains, Queue and User Interface |
41 | reset |
42 | End Sub |
43 | |
44 | |
45 | Private Sub lbx_Slots1_DblClick(ByVal Cancel As MSForms.ReturnBoolean) |
46 | ‘Selection of a Domain Variable and Queueing of Neighbours |
47 | ‘Add Selection to Label in User Interface and Internal Selection Working Memory |
48 | lbl_Slots1.Caption = lbx_Slots1.Text |
49 | strSlot1 = lbx_Slots1.Text |
50 | ‘Add unary Constraint to Queue for Collapsing |
51 | Call Main.Un_Constraint(dict_Slots1, strSlot1) |
52 | ‘Increase global counter by one |
53 | count_Slots = count_Slots + 1 |
54 | ‘Add relevant binary Constraints to Queue |
55 | Dim oConstr As iConstraint |
56 | For Each key In dict_ConList |
57 | Set oConstr = dict_ConList(key) |
58 | If oConstr.ConArg1Str = “Slots1” Then |
59 | dict_ConQue.Add (key), dict_ConList(key) |
60 | End If |
61 | If count_Slots = 3 Then |
62 | If oConstr.ConExpr = “obligation” Then |
63 | dict_ConQue.Add (key), dict_ConList(key) |
64 | End If |
65 | End If |
66 | Next |
67 | ‘Start Solver |
68 | Main.Constraint_Solver |
69 | End Sub |
70 | |
71 | |
72 | Private Sub lbx_Slots2_DblClick(ByVal Cancel As MSForms.ReturnBoolean) |
73 | lbl_Slots2.Caption = lbx_Slots2.Text |
74 | strSlot2 = lbx_Slots2.Text |
75 | Call Main.Un_Constraint(dict_Slots2, strSlot2) |
76 | count_Slots = count_Slots + 1 |
77 | Dim oConstr As iConstraint |
78 | For Each key In dict_ConList |
79 | Set oConstr = dict_ConList(key) |
80 | If oConstr.ConArg1Str = “Slots2” Then |
81 | dict_ConQue.Add (key), dict_ConList(key) |
82 | End If |
83 | If count_Slots = 3 Then |
84 | If oConstr.ConExpr = “obligation” Then |
85 | dict_ConQue.Add (key), dict_ConList(key) |
86 | End If |
87 | End If |
88 | Next |
89 | Main.Constraint_Solver |
90 | End Sub |
91 | |
92 | Private Sub lbx_Slots3_DblClick(ByVal Cancel As MSForms.ReturnBoolean) |
93 | lbl_Slots3.Caption = lbx_Slots3.Text |
94 | strSlot3 = lbx_Slots3.Text |
95 | Call Main.Un_Constraint(dict_Slots3, strSlot3) |
96 | count_Slots = count_Slots + 1 |
97 | Dim oConstr As iConstraint |
98 | For Each key In dict_ConList |
99 | Set oConstr = dict_ConList(key) |
100 | If oConstr.ConArg1Str = “Slots3” Then |
101 | dict_ConQue.Add (key), dict_ConList(key) |
102 | End If |
103 | If count_Slots = 3 Then |
104 | If oConstr.ConExpr = “obligation” Then |
105 | dict_ConQue.Add (key), dict_ConList(key) |
106 | End If |
107 | End If |
108 | Next |
109 | Main.Constraint_Solver |
110 | End Sub |
111 | |
112 | Private Sub lbx_Slots4_DblClick(ByVal Cancel As MSForms.ReturnBoolean) |
113 | lbl_Slots4.Caption = lbx_Slots4.Text |
114 | strSlot4 = lbx_Slots4.Text |
References
- Hotz, L.; Felfernig, A.; Günter, A.; Tiihonen, J. A short history of configuration technologies. In Knowledge-Based Configuration—From Research to Business Cases; Felfernig, A., Hotz, L., Bagley, C., Tiihonen, J., Eds.; Morgan Kaufmann: Waltham, MA, USA, 2014; pp. 9–19. [Google Scholar]
- Schwede, L.N.; Greve, E.; Krause, E.; Otto, K.; Moon, S.; Albers, A.; Kirchner, E.; Lachmayer, R.; Bursac, N.; Inkermann, D.; et al. How to Use the Levers of Modularity Properly—Linking Modularization to Economic Targets. J. Mech. Des. 2022, 144, 071401. [Google Scholar] [CrossRef]
- Schreiber, G. Knowledge engineering. In Foundations of Artificial Intelligence; Van Harmelen, F., Lifschitz, V., Porter, B., Eds.; Elsevier: Amsterdam, The Netherlands, 2008; Volume 3, pp. 929–946. [Google Scholar] [CrossRef]
- Gembarski, P.C. Three ways of integrating computer-aided design and knowledge-based engineering. In Proceedings of the Design Society: DESIGN Conference; Cambridge University Press: Cambridge, UK, 2020; Volume 1, pp. 1255–1264. [Google Scholar] [CrossRef]
- Durhuus, B.; Eilers, S. On the entropy of LEGO®. J. Appl. Math. Comput. 2014, 45, 433–448. [Google Scholar] [CrossRef]
- Pil, F.K.; Holweg, M. Linking product variety to order-fulfillment strategies. Interfaces 2004, 34, 394–403. [Google Scholar] [CrossRef]
- Verhagen, W.; Bermell-Garcia, P.; van Dijk, R.; Curran, R. A critical review of Knowledge-Based Engineering: An identification of research challenges. Adv. Eng. Inf. 2012, 26, 5–15. [Google Scholar] [CrossRef]
- Hopgood, A.A. Intelligent Systems for Engineers and Scientists; CRC Press: Boca Raton, FL, USA, 2016. [Google Scholar]
- McDermott, J. R1: A rule-based configurer of computer systems. Artif. Intell. 1982, 19, 39–88. [Google Scholar] [CrossRef]
- Aldanondo, M.; Hadj-Hamou, K.; Moynard, G.; Lamothe, J. Mass customization and configuration: Requirement analysis and constraint based modeling propositions. Integr. Comput.-Aided Eng. 2003, 10, 177–189. [Google Scholar] [CrossRef]
- Hvam, L.; Mortensen, N.H.; Riis, J. Product Customization; Springer Science & Business Media: Berlin/Heidelberg, Germany, 2008. [Google Scholar]
- Barták, R.; Salido, M.A.; Rossi, F. Constraint satisfaction techniques in planning and scheduling. J. Intell. Manuf. 2010, 21, 5–15. [Google Scholar] [CrossRef]
- Sabin, D.; Weigel, R. Product configuration frameworks-a survey. IEEE Intell. Syst. 1998, 13, 42–49. [Google Scholar] [CrossRef]
- Orsvärn, K.; Bennick, M.H. Use of Tacton configurator at FLSmidth. In Knowledge-Based Configuration—From Research to Business Cases; Felfernig, A., Hotz, L., Bagley, C., Tiihonen, J., Eds.; Morgan Kaufmann: Waltham, MA, USA, 2014; pp. 211–218. [Google Scholar]
- Schäffer, E.; Shafiee, S.; Mayr, A.; Franke, J. A strategic approach to improve the development of use-oriented knowledge-based engineering configurators (KBEC). Procedia CIRP 2021, 96, 219–224. [Google Scholar] [CrossRef]
- Gembarski, P.C.; Li, H.; Lachmayer, R. KBE-Modeling Techniques in Standard CAD-Systems: Case Study—Autodesk Inventor Professional. In Managing Complexity; Bellemare, J., Carrier, S., Nielsen, K., Piller, F., Eds.; Springer: Cham, Switzerland, 2017. [Google Scholar] [CrossRef]
- Hirz, M.; Dietrich, W.; Gfrerrer, A.; Lang, J. Integrated Computer-Aided Design in Automotive Development, 1st ed.; Springer: Berlin/Heidelberg, Germany, 2013. [Google Scholar]
- Skarka, W. Application of MOKA methodology in generative model creation using CATIA. Eng. Appl. Artif. Intell. 2007, 20, 677–690. [Google Scholar] [CrossRef]
- Furferi, R.; Governi, L.; Uccheddu, F.; Volpe, Y. Computer-aided design tool for GT ventilation system ductworks. Comput. Aided Des. Appl. 2018, 15, 170–179. [Google Scholar] [CrossRef]
- Milton, N. Knowledge Technologies; Polimetrica, S.a.s.: Monza, Italy, 2008; Volume 3. [Google Scholar]
- Cunis, R.; Günter, A.; Strecker, H. Das PLAKON-Buch: Ein Expertensystemkern für Planungs-und Konfigurierungs-Aufgaben in Technischen Domänen; Springer: Berlin/Heidelberg, Germany, 1991. [Google Scholar]
- Schröder, C.; Möller, R.; Lutz, C. A partial logical reconstruction of PLAKON/KONWERK. In Proceedings of the Workshop on Knowledge Representation and Configuration WRKP, Saarbrucken, Germany, 30 August 1996; pp. 55–64. [Google Scholar] [CrossRef]
- LaRocca, G. Knowledge based Engineering: Between AI and CAD. Review of a Language based Technology to Support Engineering Design. Adv. Eng. Inf. 2012, 26, 159–179. [Google Scholar] [CrossRef]
- Brailsford, S.C.; Potts, C.N.; Smith, B.M. Constraint satisfaction problems: Algorithms and applications. Eur. J. Oper. Res. 1999, 119, 557–581. [Google Scholar] [CrossRef]
- Kumar, V. Algorithms for constraint-satisfaction problems: A survey. AI Mag. 1992, 13, 32. [Google Scholar] [CrossRef]
- Petrie, C.J. Automated Configuration Problem Solving, 1st ed.; Springer: Berlin/Heidelberg, Germany, 2012. [Google Scholar]
- Juengst, W.E.; Heinrich, M. Using resource balancing to configure modular systems. IEEE Intell. Syst. 1998, 13, 50–58. [Google Scholar] [CrossRef]
- Amadori, K. Geometry Based Design Automation: Applied to Aircraft Modelling and Optimization. Ph.D. Thesis, Linköping University, Linköping, Sweden, 2012. [Google Scholar]
- Li, H.; Gembarski, P.C.; Lachmayer, R. Template-Based Design for Design Co-Creation. In Proceedings of the 5th International Conference on Design Creativity (ICDC2018), Bath, UK, 31 January–2 February 2018; pp. 387–394. [Google Scholar]
- Aldanondo, M.; Vareilles, E. Configuration for mass customization: How to extend product configuration towards requirements and process configuration. J. Intell. Manuf. 2008, 19, 521–535. [Google Scholar] [CrossRef] [Green Version]
- Pitiot, P.; Aldanondo, M.; Vareilles, E. Concurrent product configuration and process planning: Some optimization experimental results. Comput. Ind. 2014, 65, 610–621. [Google Scholar] [CrossRef]
- Kloock-Schreiber, D.; Domarkas, L.; Gembarski, P.C.; Lachmayer, R. Enrichment of geometric CAD models for service configuration. In Proceedings of the 21st International Configuration Workshop, Hamburg, Germany, 21 September 2019; pp. 22–29. [Google Scholar] [CrossRef]
Publisher’s Note: MDPI stays neutral with regard to jurisdictional claims in published maps and institutional affiliations. |
© 2022 by the author. Licensee MDPI, Basel, Switzerland. This article is an open access article distributed under the terms and conditions of the Creative Commons Attribution (CC BY) license (https://creativecommons.org/licenses/by/4.0/).
Share and Cite
Gembarski, P.C. Joining Constraint Satisfaction Problems and Configurable CAD Product Models: A Step-by-Step Implementation Guide. Algorithms 2022, 15, 318. https://doi.org/10.3390/a15090318
Gembarski PC. Joining Constraint Satisfaction Problems and Configurable CAD Product Models: A Step-by-Step Implementation Guide. Algorithms. 2022; 15(9):318. https://doi.org/10.3390/a15090318
Chicago/Turabian StyleGembarski, Paul Christoph. 2022. "Joining Constraint Satisfaction Problems and Configurable CAD Product Models: A Step-by-Step Implementation Guide" Algorithms 15, no. 9: 318. https://doi.org/10.3390/a15090318
APA StyleGembarski, P. C. (2022). Joining Constraint Satisfaction Problems and Configurable CAD Product Models: A Step-by-Step Implementation Guide. Algorithms, 15(9), 318. https://doi.org/10.3390/a15090318