-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathilp.scm
411 lines (382 loc) · 20.5 KB
/
ilp.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
#!r6rs
; This program and the accompanying materials are made available under the
; terms of the MIT license (X11 license) which accompanies this distribution.
; Author: R. Schöne
(library
(mquat ilp)
(export add-ilp-ags save-ilp make-ilp =to-ilp =ilp-eval-binvar)
(import (rnrs) (racr core) (srfi :19) (prefix (only (srfi :13) string-map) srfi:)
(mquat properties) (mquat constants) (mquat utils) (mquat ast) (mquat basic-ag))
(define (=check-model n) (att-value-call 'check-model n))
(define (=to-ilp n) (att-value-call 'to-ilp n))
(define (=ilp-name n) (att-value-call 'ilp-name n))
(define (=ilp-binvar n) (att-value-call 'ilp-binvar n))
(define (=ilp-binvar-deployed n pe) (att-value-call 'ilp-binvar-deployed n pe))
(define (=ilp-binary-vars n) (att-value-call 'ilp-binary-vars n))
(define =ilp-objective
(case-lambda ((n) (att-value-call 'ilp-objective n))
((n pe) (att-value-call 'ilp-objective n pe))))
(define (=ilp-nego n) (att-value-call 'ilp-nego n))
(define (=ilp-nego-sw n) (att-value-call 'ilp-nego-sw n))
(define (=every-clause-of n) (att-value-call 'every-clause-of n))
(define =ilp-nego-reqc
(case-lambda ((n comp) (att-value-call 'ilp-nego-reqc n comp))
((n clausetype comp) (att-value-call 'ilp-nego-reqc n clausetype comp))))
(define (=ilp-nego-hw n) (att-value-call 'ilp-nego-hw n))
(define (=req-hw-properties n) (att-value-call 'required-hw-properties n))
(define (=req-hw-clauses n) (att-value-call 'required-hw-clauses n))
(define (=every-clause n) (att-value-call 'every-clause n))
(define (=ilp-nego-hw0 n comp prop pe) (att-value-call 'ilp-nego-hw0 n comp prop pe))
(define (=ilp-eval-binvar n pe) (att-value-call 'ilp-eval-binvar n pe))
(define prepend-sign (lambda (val) (if (< val 0) val (string-append "+ " (number->string val)))))
; TODO make bidirectional mapping: {_ - +} -> {_0 _1 _2}
(define subs (list (list #\- #\_) (list #\+ #\_)))
(define (ilp-conform-name name) (srfi:string-map (lambda (c) (let ([entry (assq c subs)]) (if entry (cadr entry) c))) name))
(define (comp-name comp) (ilp-conform-name (comp->name comp)))
(define (make-constraints provs max-reqs min-reqs request?)
(fold-left ; fold over provisions
(lambda (constraints prov-entry)
(let ([max-req-entry (assq (car prov-entry) max-reqs)]
[min-req-entry (assq (car prov-entry) min-reqs)])
(cons-if (and max-req-entry (make-constraint (car prov-entry) (cadr prov-entry)
(cadr max-req-entry) comp-max-eq request?))
(cons-if (and min-req-entry (make-constraint (car prov-entry) (cadr prov-entry)
(cadr min-req-entry) comp-min-eq request?))
constraints)))) (list) provs))
(define (make-constraint prop prov-entry req-entry comp request?)
(if request?
(append
(list (string-append "request(" (=ilp-name prop) "_" (comp-name comp) "): "))
(fold-left (lambda (constraint pair) (cons* (prepend-sign (car pair)) (cadr pair) constraint)) (list) prov-entry)
(cons* (comp->rev-string comp) (car req-entry)))
(let ([f-prov (if (eq? comp comp-max-eq)
; prov for max: (maximum - val)
(lambda (constraint val name) (cons* (prepend-sign (- (=maximum prop) val)) name constraint))
(lambda (constraint val name) (cons* (prepend-sign val) name constraint)))] ; prov for other: val
[f-req (if (eq? comp comp-max-eq)
; req for max: - (maximum - val) = val - maximum
(lambda (constraint val name) (cons* (prepend-sign (- val (=maximum prop))) name constraint))
(lambda (constraint val name) (cons* (prepend-sign (- val)) name constraint)))]) ; req for other: -val
; (debug "mc: prov-entry:" prov-entry ",req-entry:" req-entry ",maximum:" maximum ",name:" prov)
(append
(list (string-append (=ilp-name prop) "_" (comp-name comp) ": "))
(fold-left (lambda (constraint pair) (f-prov constraint (car pair) (cadr pair))) (list) prov-entry)
(fold-left (lambda (constraint pair) (f-req constraint (car pair) (cadr pair))) (list) req-entry)
(list ">= 0")))))
(define (cons-if x y) (if x (cons x y) y))
(define (f-val-signed comp prop)
(if (eq? comp comp-max-eq)
(lambda (val) (prepend-sign (- (=maximum prop) val))) ; for max: (maximum - val)
(lambda (val) (prepend-sign val))))
(define (save-ilp path root) (save-to-file path (=to-ilp root)))
(define (make-ilp root) (save-ilp "gen/ilp.txt" root))
(define (eq-pair? p1 p2) (and (eq? (car p1) (car p2)) (eq? (cdr p1) (cdr p2))))
(define (add-to-al-paired al key val op)
(if (null? al) (list (list key (op val (list)))) ; make new entry
(let ([entry (car al)])
(if (eq-pair? (car entry) key)
(cons (list key (op val (cadr entry))) (cdr al)) ; add to entry and return
(cons entry (add-to-al-paired (cdr al) key val op)))))) ; recur
(define (merge-paired-al al1 al2)
(fold-left (lambda (big-al entry) (add-to-al-paired big-al (car entry) (cadr entry) append)) al1 al2))
(define (maybe-names l) (map (lambda (x) (if (and (ast-node? x) (ast-has-child? 'name x)) (->name x) x)) l))
(define times (list))
(define (ctf att-name f . args) ; [c]ons [t]imed [f]unction
(if timing? (let ([result (time-it (lambda _ (apply f args)))])
(set! times (cons (list (current-date-formatted) att-name (time-second (cdr result))
(time-nanosecond (cdr result)) (maybe-names args)) times))
(car result))
(apply f args)))
(define (add-ilp-ags mquat-spec)
(with-specification
mquat-spec
(ag-rule
check-model
(Root
(lambda (n)
(att-value-compute 'check-model)
(when (= 0 (length (=every-pe n))) (warn "No resources found"))
(when (= 0 (length (=every-container n))) (warn "No container found"))
(when (= 0 (length (=every-comp n))) (warn "No component found for request"))
(when (= 0 (length (=every-impl n))) (warn "No implementation found for request"))
(when (= 0 (length (=every-mode n))) (warn "No modes found for request")))))
;;; ILP-Creation rules
; Return a list of 1 objective, some constraints, some bounds and some generals, everything
; packed inside a list, e.g. one constraint is also a list.
(ag-rule
to-ilp
(Root
(lambda (n)
(att-value-compute 'to-ilp)
(=check-model n)
(let* ([binary-vars (=ilp-binary-vars n)]
[result
(list
(list "Minimize")
(=ilp-objective n)
(list "Subject To")
(append
; (debug (list) "request")
(=to-ilp (<=request n)) ; request-constraints
; (debug (list) "arch-c")
(=to-ilp (->SWRoot n)) ; archtitecture-constraints
; (debug (list) "nfp-nego")
(=ilp-nego n)) ; NFP-negotiation
; (debug (list) "bounds")
(list "Bounds")
(append
(map (lambda (var) (list 0 "<=" var "<=" 1)) binary-vars))
; (debug (list) "generals")
(list "Generals")
binary-vars
(list "End"))])
(if profiling? (cons result (get-counts)) result))))
(Request (lambda (n) (att-value-compute 'to-ilp) (=ilp-nego-sw n)))
; (SWRoot (lambda (n) (recur n append =to-ilp ->Comp*)))
(SWRoot (lambda (n) (att-value-compute 'to-ilp) (fold-left (lambda (result c) (append (=to-ilp c) result))
(list) (=every-comp n))))
(Comp
(lambda (n)
(att-value-compute 'to-ilp)
(debug "Comp:" (->name n))
; (display (=req-hw-clauses n))
(cons
(fold-left
(lambda (result entry)
(cons
(append
(list (string-append (=ilp-name n) "_requires_" (=ilp-name (car entry)) ": "))
(fold-left (lambda (inner impl) (cons* "-" (=ilp-binvar impl) inner)) (list) (cadr entry))
(fold-left (lambda (inner impl) (cons* "+" (=ilp-binvar impl) inner)) (list)
(->* (->Impl* (car entry))))
(list ">=" 0)) result))
(list) (=req-comp-map n))
(recur n cons =to-ilp ->Impl*))))
(Impl
(lambda (n)
(att-value-compute 'to-ilp)
(debug "Impl:" (->name n))
(cons (string-append "single(" (=ilp-name n) "): ")
(fold-left ; deploy one combination of mode and pe for this impl
(lambda (result pe)
(append (fold-left (lambda (inner mode) (cons* "+" (=ilp-binvar-deployed mode pe) inner))
(list) (->* (->Mode* n))) result))
(list "-" (=ilp-binvar n) "=" 0)
(=every-container n))))))
(ag-rule request-target? (Comp (lambda (n) (eq? (=target (<=request n)) n))))
(ag-rule
ilp-objective
(Root
(lambda (n)
(att-value-compute 'ilp-objective)
(fold-left
(lambda (result mode)
(cons*
(fold-left (lambda (inner pe) (append (=ilp-objective pe mode) inner))
(list) (=every-container n))
result))
(list) (=every-mode n))))
(Resource (lambda (n mode) (att-value-compute 'ilp-objective)
(debug n mode) (list (prepend-sign (=eval-on (=provided-clause mode (=objective-name n))
(=type n)))
(=ilp-binvar-deployed mode n)))))
; Creates a list of NFP-negotiation constraints
(ag-rule
ilp-nego
(Root (lambda (n) (att-value-compute 'ilp-nego) (remove (list) (=ilp-nego (->SWRoot n))))) ; remove empty constraints
(SWRoot (lambda (n) (att-value-compute 'ilp-nego) (fold-left (lambda (result c) (append (=ilp-nego c) result))
(list) (=every-comp n))))
(Comp (lambda (n) (att-value-compute 'ilp-nego) (append (=ilp-nego-sw n)
(=ilp-nego-hw n)))))
(ag-rule
ilp-nego-sw
(Comp
(lambda (n)
(att-value-compute 'ilp-nego-sw)
(fold-left ; fold over req-comp-map
(lambda (result entry)
(append
(make-constraints
(=ilp-nego-reqc (car entry) 'ProvClause comp-eq) ;provs
(=ilp-nego-reqc n 'ReqClause comp-max-eq) ;max-reqs
(=ilp-nego-reqc n 'ReqClause comp-min-eq) #f) ;min-reqs,request?
result)) (list) (=req-comp-map n))))
(Request
(lambda (n)
(att-value-compute 'ilp-nego-sw)
(cons (cons "request_target: " (fold-left (lambda (result impl) (cons* "+" (=ilp-binvar impl) result))
(list "=" 1) (->* (->Impl* (=target n)))))
(make-constraints
(=ilp-nego-reqc (=target n) 'ProvClause comp-eq) ;provs
(=ilp-nego-reqc n comp-max-eq) ;max-reqs
(=ilp-nego-reqc n comp-min-eq) #t))))) ;min-reqs,request?
(ag-rule
ilp-nego-reqc
(Comp ;→ (prop ((prop-value deployed-mode-name) ... ))-pairs for each Clause with correct type in each mode of each impl
(lambda (n clausetype comparator) (att-value-compute 'ilp-nego-reqc)
(recur n merge-al =ilp-nego-reqc ->Impl* clausetype comparator)))
; (lambda (n clausetype comparator)
; (fold-left
; (lambda (result clause)
; (if (and (ast-subtype? clause clausetype) (eq? (->comparator clause) comparator))
; (fold-left ; fold over pe
; (lambda (inner pe)
; (add-to-al inner (=real (->ReturnType clause))
; (list (=eval-on clause pe) (=ilp-binvar-deployed (<<- clause) pe))))
;; (=ilp-eval-binvar clause pe)))
; result (=every-container n))
; result))
;; (list) (append (=every-clause-of n) (->* (->Constraints (<=request n)))))))
; (list) (=every-clause-of n))))
(Impl ;→ (prop ((prop-value deployed-mode-name) ... ))-pairs for each Clause with correct type in each mode
(lambda (n clausetype comparator) (att-value-compute 'ilp-nego-reqc)
(recur n merge-al =ilp-nego-reqc ->Mode* clausetype comparator)))
(Mode ;→ (prop ((prop-value deployed-mode-name) ... ))-pairs for each Clause with correct type
(lambda (n clausetype comparator)
(att-value-compute 'ilp-nego-reqc)
(fold-left
(lambda (result clause)
(if (and (ast-subtype? clause clausetype) (eq? (->comparator clause) comparator))
(fold-left ; fold over pe
(lambda (inner pe)
(add-to-al inner (=real (->ReturnType clause))
(list (=eval-on clause pe) (=ilp-binvar-deployed n pe))))
result (=every-container n))
result))
; (list) (att-value 'combined-reqs n))))
(list) (->* (->Clause* n)))))
(Request
(lambda (n comparator)
(att-value-compute 'ilp-nego-reqc)
(fold-left
(lambda (result clause)
(if (eq? (->comparator clause) comparator)
(add-to-al result (=real (->ReturnType clause)) (list (=eval-on clause #f) "")) ;use arbitrary target #f
result))
(list) (->* (->Constraints n))))))
(ag-rule
every-clause-of
(Comp
(lambda (n) (fold-left (lambda (result mode) (append (->* (->Clause* mode)) result)) (list) (=every-mode n)))))
; (ag-rule
; ilp-nego-rc-req
; (Comp
; (lambda (n) ; → all properties required in here. ([prop (clause ... )] ... )
; (fold-left
;; (lambda (result clause) (let ([prop (=real (->ReturnType clause))])
;; (if (member prop result) result (cons prop result))))
; (lambda (result clause) (add-to-al result (=real (->ReturnType clause)) clause))
; (list) (=every-clause-of n)))))
;
; (ag-rule
; ilp-nego-sw-v2
; (Comp
; (lambda (n)
; (fold-left (lambda (result pc) (make-constraints2 (cdr pc) (=every-prov-clause (car pc) comp-max-eq)
; (=every-prov-clause (car pc) comp-min-eq)))
; (list) (=ilp-nego-rc-req n)))))
;
; (define (make-constraints2 prov-clauses req-clauses) #f)
; (define (=ilp-nego-rc-req n) (att-value '=ilp-nego-rc-req n))
(ag-rule combined-reqs (Mode (lambda (n) (append (->* (->Clause* n))
(->* (->Constraints (<=request n)))))))
(ag-rule
ilp-nego-hw
(Comp
(lambda (n)
(att-value-compute 'ilp-nego-hw)
(fold-left
(lambda (result entry) ; entry = {(comparator . property) { clauses }}
(append
(fold-left
(lambda (inner pe) (cons (append
(ctf "ilp-nego-hw0" =ilp-nego-hw0 n (caar entry) (cdar entry) pe)
(list "<=" ((f-val-signed (caar entry) (cdar entry))
(=eval-on (=provided-clause pe (->name (cdar entry))
(=type pe)) pe))))
inner))
(list) (=every-container n))
result))
(list) (=req-hw-clauses n)))))
(ag-rule
ilp-nego-hw0
(Comp
(lambda (n comp prop pe)
(att-value-compute 'ilp-nego-hw0)
(debug "hw0-comp" (->name n) comp (->name prop) (->name pe))
(let* ([cp (cons comp prop)]
; [__ (begin (debug (assp (lambda (x) (eq-pair? cp x)) (=req-hw-clauses n)))
; (debug (cadr (assp (lambda (x) (eq-pair? cp x)) (=req-hw-clauses n)))))]
[lop (fold-left ;here we have a [l]ist [o]f [p]airs (evaled-prop mode-on-pe-name)
(lambda (result cl) (cons (=ilp-eval-binvar cl pe) result))
(list) (cadr (assp (lambda (x) (eq-pair? cp x)) (=req-hw-clauses n))))]
[f (f-val-signed comp prop)]) ; for other: val
(append (list (string-append (=ilp-name n) "_" (=ilp-name prop) "_"
(=ilp-name pe) "_" (comp-name comp) ": "))
(fold-left (lambda (result p) #|(debug p)|# (cons* (f (car p)) (cadr p) result)) (list) lop)
; (list "<=" (f (=eval-on (=provided-clause pe (->name prop)
; (=type pe)) pe)))
)))))
(ag-rule
ilp-eval-binvar
(Clause
(lambda (n pe)
(att-value-compute 'ilp-eval-binvar)
; (let ([real-ReturnType (=real (->ReturnType n))])
(debug "ilp-eval-binvar" n (->name pe))
; (if (or (eq? (=type pe) (<<- real-ReturnType))
; (ast-subtype? (<<- real-ReturnType) 'HWRoot))
(list (=eval-on n (=type pe)) (=ilp-binvar-deployed (<<- n) pe))
; (begin (debug "not suitable" real-ReturnType pe) (list))))
))) ;empty pair if not a suitable clause
(ag-rule
required-hw-properties
(Comp (lambda (n) (att-value-compute 'required-hw-properties) (recur n union =req-hw-properties ->Impl*)))
(Impl (lambda (n) (att-value-compute 'required-hw-properties) (recur n union =req-hw-properties ->Mode*)))
(Mode (lambda (n) (att-value-compute 'required-hw-properties) (recur n union =req-hw-properties ->Clause*)))
(Clause
(lambda (n)
(att-value-compute 'required-hw-properties)
(let ([prop (=real (->ReturnType n))])
(if (and (ast-subtype? n 'ReqClause) (=hw? prop))
(list (list (->comparator n) prop)) (list))))))
(ag-rule
required-hw-clauses ; computes {(comp . prop) {clause1 .. clauseN} ... } for each comparator and prop
(Comp (lambda (n) (att-value-compute 'required-hw-clauses) (recur n merge-paired-al =req-hw-clauses ->Impl*)))
(Impl (lambda (n) (att-value-compute 'required-hw-clauses) (recur n merge-paired-al =req-hw-clauses ->Mode*)))
(Mode (lambda (n) (att-value-compute 'required-hw-clauses) (recur n merge-paired-al =req-hw-clauses ->Clause*)))
(Clause
(lambda (n)
(att-value-compute 'required-hw-clauses)
(let ([prop (=real (->ReturnType n))])
(if (and (ast-subtype? n 'ReqClause) (=hw? prop))
(list (list (cons (->comparator n) prop) (list n))) (list))))))
(ag-rule
ilp-binary-vars
(Root
(lambda (n)
(att-value-compute 'ilp-binary-vars)
(append
(map (lambda (impl) (=ilp-binvar impl)) (=every-impl n))
(fold-left (lambda (result mode) (append (map (lambda (pe) (=ilp-binvar-deployed mode pe))
(=every-container n)) result))
(list) (=every-mode n))))))
(ag-rule
ilp-name
(Property (lambda (n) (att-value-compute 'ilp-name) (ilp-conform-name (->name n))))
(Comp (lambda (n) (att-value-compute 'ilp-name) (ilp-conform-name (->name n))))
(Impl (lambda (n) (att-value-compute 'ilp-name) (ilp-conform-name (->name n))))
(Mode (lambda (n) (att-value-compute 'ilp-name) (ilp-conform-name (->name n))))
(Resource (lambda (n) (att-value-compute 'ilp-name) (ilp-conform-name (->name n)))))
(ag-rule
ilp-binvar
(Impl (lambda (n) (att-value-compute 'ilp-binvar) (ilp-conform-name (string-append "b#" (->name (<=comp n))
"#" (if (lonely? n) "" (->name n))))))
(Mode (lambda (n) (att-value-compute 'ilp-binvar) (error "Should not be called for Modes"))))
(ag-rule
ilp-binvar-deployed
(Mode (lambda (n pe)
(att-value-compute 'ilp-binvar-deployed)
(let ([impl (<=impl n)])
(ilp-conform-name (string-append "b#" (->name (<=comp impl)) "#" (if (lonely? impl) "" (->name (<=impl n)))
"#" (if (lonely? n) "" (->name n)) "#" (->name pe))))))))))