2
(include-book ;; Newline to fool ACL2/cert.pl dependency scanner
4
(acl2::begin-book t :ttags :all);$ACL2s-Preamble$|#
7
Polymorphic signatures (sig macro)
10
date created: [2014-08-06 Sun]
11
data last modified: [2014-08-07]
14
(in-package "DEFDATA")
16
(include-book "defdata-core")
19
; DEFDATA POLYMORPHIC SUPPORT EVENT GENERATION FUNCTIONS.
22
(defconst *allowed-type-vars* '(:a :b :c :d :a1 :b1 :c1 :d1 :a2 :b2 :c2 :d2))
24
(defconst *tvar-typename-alist*
38
; type var expr -> psig fun instance template
39
; where type var expr is the dominating polymorphic argument expr in a sig form
40
(table psig-template-map nil) ;UNUSED now -- but seems like a more general idea to support arbitrary polymorphic type expressions. REVISIT
42
(defstub psig-templ-instantiation-ev (* * * * * * *) => *)
43
(defloop psig-inst-templates (tname tvar-sigma templates new-types kwd-alist wrld)
44
(for ((templ in templates))
45
(append (psig-templ-instantiation-ev tname tvar-sigma templ (table-alist 'derived-pred->poly-texp-map wrld) new-types kwd-alist wrld))))
49
(defun one-way-unify (pat term)
50
(if (and (pseudo-termp pat)
52
(acl2::one-way-unify pat term)
55
(defun polymorphic-inst-defdata-events1 (p top-kwd-alist wrld)
56
(b* (((cons name A) p)
57
;; (pdef (cdr (assoc-eq 'pdef A)))
58
;; (kwd-alist (cdr (assoc-eq 'kwd-alist A)))
59
((acl2::assocs pdef new-types kwd-alist) A)
60
; (- (cw "pdef : ~x0" pdef))
61
((unless (consp pdef)) '())
62
(kwd-alist (append kwd-alist top-kwd-alist))
64
(U (table-alist 'user-combinator-table wrld))
65
(C (table-alist 'data-constructor-table wrld))
66
;TODO: at some time i should support polymorphic cons, but perhaps this is done by tau already SIMPLE BUT GOOD RESEARCH Question/Experiment.
67
; Or rather simply use a separate table psig-template-map to support polymorphism more generally
68
(meta-kwd-alist (or (cdr (assoc-eq comb U)) (cdr (assoc-eq comb C))))
70
(template (get1 :polymorphic-events meta-kwd-alist))
71
(ptype (get1 :polymorphic-type-form meta-kwd-alist))
72
; (- (cw "ptype : ~x0 tmpl: ~x1" ptype template))
73
((when (null ptype)) '()) ;no poly support
75
(pdef (remove-names pdef))
76
;(one-way-unify '(alistof :a :b) '(alistof nat symbol-list))
77
;(T ((:B . SYMBOL-LIST) (:A . NAT)))
78
((mv yesp tvar-sigma) (one-way-unify (acl2::sublis-var *tvar-typename-alist* ptype) pdef))
80
(verbose (get1 :verbose kwd-alist t))
82
(- (cw? (and (not yesp) verbose) "~|Defdata/Note: Failed to unify ~x0 with ~x1. Skipping polymorphic instantiation events...~%" ptype pdef))
85
(psig-templ-instantiation-ev name tvar-sigma template (table-alist 'derived-pred->poly-texp-map wrld) new-types kwd-alist wrld)))
90
(defloop polymorphic-inst-defdata-events0 (ps kwd-alist wrld)
91
(for ((p in ps)) (append (polymorphic-inst-defdata-events1 p kwd-alist wrld))))
93
(defun polymorphic-inst-defdata-events (ps kwd-alist wrld)
94
(b* ((events (polymorphic-inst-defdata-events0 ps kwd-alist wrld)))
97
`(commentary ,(get1 :print-commentary kwd-alist) "~| Polymorphic sig instantiation events...~%")
101
(add-pre-post-hook defdata-defaults-table :post-hook-fns '(polymorphic-inst-defdata-events))
107
; The rest of the file concerns with the implementation of the SIG macro
111
; sig macro for polymorphic support.
113
; I dont think we are ever going to have more than 3 type parameters, but lets start with 12.
146
(local (defun A1p (v)
150
(local (defun B1p (v)
154
(local (defun C1p (v)
158
(local (defun D1p (v)
162
(local (defun A2p (v)
166
(local (defun B2p (v)
170
(local (defun C2p (v)
174
(local (defun D2p (v)
179
(defthm Ap-is-predicate
182
(defthm Bp-is-predicate
185
(defthm Cp-is-predicate
188
(defthm Dp-is-predicate
191
(defthm A1p-is-predicate
194
(defthm B1p-is-predicate
197
(defthm C1p-is-predicate
200
(defthm D1p-is-predicate
203
(defthm A2p-is-predicate
206
(defthm B2p-is-predicate
209
(defthm C2p-is-predicate
212
(defthm D2p-is-predicate
217
;(defconst *allowed-type-var->named-type-binding* (pairlis$ *allowed-type-vars* *tvar-typename-alist*))
220
;ACHTUNG: make sure people dont use names from defdata namespace. Note that A,Ap,... reside in defdata namespace.
221
(defconst *initial-tvar-M* (type-metadata-bases (strip-cdrs *tvar-typename-alist*) "DEFDATA"))
223
;maps typenames of type vars to metadata like in M.
224
;e.g. A -> Ap nth-A etc
225
(table tvar-metadata-table nil *initial-tvar-M* :clear)
228
(defun collect-type-vars-texp (texp ctx)
229
(cond ((quotep texp) '())
230
((keywordp texp) (list texp))
232
((not (true-listp texp)) ;right now we dont support named texp
233
(er hard? ctx "~| ~x0 : Named type expressions not supported.~%" texp))
234
(t (collect-type-vars-texps (cdr texp) ctx))))
235
(defun collect-type-vars-texps (texps ctx)
238
(union-eq (collect-type-vars-texp (car texps) ctx)
239
(collect-type-vars-texps (cdr texps) ctx))))
243
(defun collect-undefined-typenames-texp (texp ctx wrld)
244
(cond ((quotep texp) '())
245
((keywordp texp) '())
246
((atom texp) (if (predicate-name texp) '() (list texp)))
247
((not (true-listp texp)) ;right now we dont support named texp
248
(er hard? ctx "~| ~x0 : Named type expressions not supported.~%" texp))
249
(t (collect-undefined-typenames-texps (cdr texp) ctx wrld))))
250
(defun collect-undefined-typenames-texps (texps ctx wrld)
253
(union-eq (collect-undefined-typenames-texp (car texps) ctx wrld)
254
(collect-undefined-typenames-texps (cdr texps) ctx wrld))))
258
;(include-book "coi/util/pseudo-translate" :dir :system)
260
(defconst *sig-keywords* '(:hints :rule-classes :verbose :satisfies))
262
;check -- also take care of monomorphic sig, but make sure only tnames are allowed!
263
(defun parse-sig (args ctx wrld)
264
(declare (ignorable wrld))
265
(b* (((mv sig kwd-val-list) (separate-kwd-args args '()))
266
((mv kwd-alist rest) (extract-keywords ctx *sig-keywords* kwd-val-list '()))
268
((unless (null rest)) (er hard? ctx "~| Extra args: ~x0~%" rest))
269
(dep-hyp (get1 :satisfies kwd-alist))
270
(x123vars (numbered-vars 'ACL2S::X (len *allowed-type-vars*)))
271
(dep-vars (and dep-hyp (all-vars dep-hyp))) ;BEWARE all-vars works only for terms; it might return nil and t as variables. Use pseudo-translate here.
272
((unless (subsetp dep-vars x123vars))
273
(er hard? ctx "~| Only variable arguments allowed in SATISFIES are ~x0; but given ~x1~%" x123vars dep-vars))
274
(dep-hyps (cond ((null dep-hyp) nil)
275
((or (eq dep-hyp 't) (equal dep-hyp ''t)) nil)
276
((atom dep-hyp) (list dep-hyp))
277
((eq (car dep-hyp) 'ACL2::AND) (cdr dep-hyp))
278
((proper-symbolp (car dep-hyp)) (list dep-hyp))
280
(kwd-alist (put-assoc-eq :satisfies dep-hyps kwd-alist))
281
;(- (cw "sig = ~x0 kwd-alist = ~x1 " sig kwd-alist))
285
((name arg-type-list 'ACL2::=> return-type)
286
(b* (((unless (proper-symbolp name))
287
(er hard? ctx "~| Name ~x0 should be a symbol.~%" name))
288
;simple syntax checks
289
(& (check-syntax-texps arg-type-list '() '() ctx wrld))
290
(undefined-typenames (collect-undefined-typenames-texps (cons return-type arg-type-list) ctx wrld))
291
((when (consp undefined-typenames))
292
(er hard? ctx "~| Undefined types: ~x0~%" undefined-typenames))
293
(arg-type-vars (collect-type-vars-texps arg-type-list ctx))
294
(return-type-vars (collect-type-vars-texp return-type ctx))
295
((unless (subsetp return-type-vars arg-type-vars))
296
(er hard? ctx "~| Return type variables should be from ~x0.~%" arg-type-vars))
297
; todo: do the mapping from current keyword type variables to :a :b ...
298
((unless (subsetp arg-type-vars *allowed-type-vars*))
299
(er hard? ctx "~| Sorry for the inconvenience, but could you please try again choosing type variables from ~x0.~%" *allowed-type-vars*)))
301
(list name arg-type-list return-type kwd-alist)))
303
(& (er hard? ctx "~| General form: (sig name arg-type-list => return-type).~%" )))))
307
(defun to-symbol (obj pkg)
308
(declare (xargs :guard (and (stringp pkg)
309
(not (equal pkg "")))))
312
(b* (((mv & str) (acl2::fmt1!-to-string "~x0" (acons #\0 obj '()) 0)))
315
(defloop to-symbols (objs pkg)
316
(declare (xargs :guard (and (stringp pkg)
317
(not (equal pkg "")))))
318
(for ((o in objs)) (collect (to-symbol o pkg))))
320
;; (defun map-fn (lst f rest-args ctx w)
323
;; (cons (funcall-w f (cons (car lst) rest-args) ctx w)
324
;; (map-fn (cdr lst) f rest-args ctx w))))
326
;; (defmacro map (lst f w &key rest-args)
327
;; `(map-fn ,lst ,f ,rest-args ,w))
330
(defun assoceqlst1 (key A)
331
(let ((entry (assoc-eq key A)))
332
(and entry (list entry))))
335
(defloop assoc-eq-lst (keys A)
336
(for ((key in keys)) (append (assoceqlst1 key A))))
338
(defun stitch-up-defuns (names params-lst decls bodies)
341
(cons (if (consp decls);not null (only include declare if its not empty)
342
(list 'DEFUN (car names) (car params-lst) (car decls) (car bodies))
343
(list 'DEFUN (car names) (car params-lst) (car bodies)))
344
(stitch-up-defuns (cdr names)
350
(defun make-derived-tvar-type-defthm (pred texp)
352
(('LISTOF &) `((defthm ,(s+ pred '-IMPLIES-TLP)
355
:hints (("Goal" :in-theory (enable true-listp)))
356
:rule-classes ((:forward-chaining)
357
(:compound-recognizer)
358
;(:rewrite :backchain-limit-lst 1)
361
(('ALISTOF &) `((defthm ,(s+ pred '-IMPLIES-ALISTP)
364
:hints (("Goal" :in-theory (enable ,pred alistp)))
365
:rule-classes ((:forward-chaining)))))
369
(defloop make-derived-tvar-type-defthms (preds texps)
370
(for ((p in preds) (texp in texps))
371
(append (make-derived-tvar-type-defthm p texp))))
374
;TODO.limitation -- Using just name for the clique tnames (LIMITATION)."
375
(defloop parse-top-texps (names texps ctx wrld)
376
(for ((name in names) (texp in texps))
377
(collect (parse-top-texp name texp (list name) ctx wrld))))
380
(defun make-sig-tvar-support-events (texps ctx wrld)
381
"for each undefined tvar texp, define its predicate and if possible its type defthm"
382
(b* ((M (append (table-alist 'tvar-metadata-table wrld)
383
(table-alist 'type-metadata-table wrld)))
384
(texps (remove-names-lst (remove-duplicates-equal texps)))
385
(tnames (to-symbols texps "DEFDATA"))
387
(undef-tnames (set-difference-eq tnames (strip-cars (assoc-eq-lst tnames M))))
389
(undef-nm-texp-alst (assoc-eq-lst undef-tnames (pairlis$ tnames texps)))
390
; (- (cw "nm-texp-alst: ~x0 undef-tnames: ~x1 undef-nm-texp-alst: ~x2" nm-texp-alst undef-tnames undef-nm-texp-alst))
391
((mv undef-tnames undef-texps) (mv (strip-cars undef-nm-texp-alst) (strip-cdrs undef-nm-texp-alst)))
392
(undef-n-types (parse-top-texps undef-tnames undef-texps ctx wrld))
395
(C (table-alist 'data-constructor-table wrld))
396
(B (table-alist 'builtin-combinator-table wrld))
397
(new-types (type-metadata-bases undef-tnames "DEFDATA"))
398
(M (append new-types M))
399
(undef-pred-bodies (make-pred-Is undef-n-types (make-list (len undef-n-types) :initial-element 'x) nil M C B wrld))
400
(undef-pred-names (make-predicate-symbol-lst undef-tnames "DEFDATA")))
402
(append (stitch-up-defuns undef-pred-names
403
(make-list (len undef-pred-names) :initial-element '(x))
406
(make-derived-tvar-type-defthms undef-pred-names undef-texps))))
409
(defconst *poly-combinators* '(listof alistof map))
411
;map: pred name -> actual tvar comb exp
412
(table derived-pred->poly-texp-map nil)
414
(defloop table-put-events (tble-name keys vals)
415
(for ((key in keys) (val in vals))
416
(collect `(TABLE ,tble-name ',key ',val :put))))
418
(defconst *sig-singular-dominant-poly-comb-limitation-msg*
419
"~| SIG: Limitation -- There should be one polymorphic combinator argument that dominates all other arguments. ~
420
But ~x0 does not have this property. Therefore we are unable to functionally instantiate this polymorphic signature. ~
421
Please send this example to the implementors for considering removal of this restriction.~%")
423
(defun all-tvars (texp)
424
(intersection-eq (strip-cdrs *tvar-typename-alist*) (all-vars texp)))
426
(defun all-tvars-lst (texps)
427
(intersection-eq (strip-cdrs *tvar-typename-alist*) (all-vars1-lst texps '())))
429
(defun poly-type-size (ptype)
434
(listof (+ 2 (poly-type-size (cadr ptype))))
435
(alistof (+ 3 (+ (poly-type-size (second ptype)) (poly-type-size (third ptype)))))
436
(map (+ 4 (+ (poly-type-size (second ptype)) (poly-type-size (third ptype)))))
440
(defun choose-largest-poly-type (ptypes ans)
443
(if (> (poly-type-size (car ptypes)) (poly-type-size ans))
444
(choose-largest-poly-type (cdr ptypes) (car ptypes))
445
(choose-largest-poly-type (cdr ptypes) ans))))
447
(defun pick-dominant-poly-type-expr1 (ptypes all-tvars answers)
449
(choose-largest-poly-type answers (car answers))
450
(if (subsetp all-tvars (all-tvars (car ptypes)))
451
(pick-dominant-poly-type-expr1 (cdr ptypes) all-tvars (cons (car ptypes) answers))
452
(pick-dominant-poly-type-expr1 (cdr ptypes) all-tvars answers))))
454
(defun pick-dominant-poly-type-expr (ptypes)
455
(pick-dominant-poly-type-expr1 ptypes (all-tvars-lst ptypes) nil))
457
(defun make-table-append-event2 (tble-name key1 key2 val wrld)
458
(b* ((A (table-alist tble-name wrld))
459
(existing-alst (get1 key1 A))
460
(new-val (append (get1 key2 existing-alst) val))
461
(new-alst (put-assoc-eq key2 new-val existing-alst)))
462
`(TABLE ,tble-name ',key1 ',new-alst :put)))
464
(defun filter-texps-with-vars (texps)
465
"Filter from normalized texps, the ones which have :a, :b, ... type vars"
468
(if (consp (all-tvars (car texps)))
469
(cons (car texps) (filter-texps-with-vars (cdr texps)))
470
(filter-texps-with-vars (cdr texps)))))
473
(defun register-poly-sig-events (nm atypes rtype templ wrld)
474
;sig: proper-symbol * texps * texp * template * world -> events
475
(b* ((dom-atype (pick-dominant-poly-type-expr atypes))
476
(- (cw? nil "dom-atype: ~x0 nm: ~x1" dom-atype nm))
477
((when (null dom-atype))
478
(prog2$ (cw *sig-singular-dominant-poly-comb-limitation-msg* atypes) nil)))
479
(and (consp dom-atype)
480
(b* ((pcomb (car dom-atype))
481
((unless (member-eq pcomb *poly-combinators*))
483
(cw "~x0 currently does not have polymorphic support. Skipping..." pcomb)
485
(vtypes (filter-texps-with-vars (remove-duplicates-equal (cons rtype atypes))))
486
(vtnames (to-symbols vtypes "DEFDATA"))
487
(vpreds (make-predicate-symbol-lst vtnames "DEFDATA")))
488
; now add a table entry to type-var table to map arg-pred names to their arg-types, this will help find the correct instantiation alist.
489
; then add the template to the corresponding user-combinator polymorphic-events entry!
490
`(,@(table-put-events 'derived-pred->poly-texp-map vpreds vtypes) ;possibly redundant
491
,@(table-put-events 'tvar-metadata-table vtnames (strip-cdrs (type-metadata-bases vtnames "DEFDATA")))
492
,(make-table-append-event2 'user-combinator-table pcomb :polymorphic-events templ wrld))))))
496
(defun find-type-name (texp M)
499
(b* (((cons tname al) (car M))
500
(pdef (get1 :prettyified-def al)))
502
(if (equal texp pdef) ;a very strong check == we should have a weaker (better) equality
504
(find-type-name texp (cdr M))))))
506
;get typenames for certain type expressions e.g (listof nat) has the type name nat-list
508
(defloop find-type-names1 (texps M)
509
(for ((texp in texps)) (collect (if (and (proper-symbolp texp) (assoc-eq texp M))
511
(find-type-name texp M)))))
515
(defun remove-exprs-with-fns (psigs fns)
518
(if (intersection-eq (acl2::all-fnnames (car psigs)) fns)
519
(remove-exprs-with-fns (cdr psigs) fns)
521
(remove-exprs-with-fns (cdr psigs) fns)))))
524
(defun subst-vals (map sigma)
525
"apply sigma to all values in map"
528
(b* (((cons key val) (car map))
529
(val~ (acl2::sublis-var sigma val)))
530
(cons (cons key val~)
531
(subst-vals (cdr map) sigma)))))
534
; refactor these two functions TODO
535
(defun undefined-preds (pred->tname-map)
536
"return all keys marked :undefined"
537
(if (endp pred->tname-map)
539
(if (equal (cdr (car pred->tname-map)) :undefined)
540
(cons (caar pred->tname-map)
541
(undefined-preds (cdr pred->tname-map)))
542
(undefined-preds (cdr pred->tname-map)))))
544
(defun remove-undefined (map)
545
"remove all values marked :undefined"
548
(if (equal (cdr (car map)) :undefined)
549
(remove-undefined (cdr map))
551
(remove-undefined (cdr map))))))
554
(defun predicate-name/lambda (type M)
555
"find predicate characterization for type (either a symbol or a quoted
556
constant). In the latter return a lambda expression"
557
(declare (xargs :guard (and (or (proper-symbolp type) (possible-constant-value-p type))
559
(cond ((proper-symbolp type) (predicate-name type M))
560
((possible-constant-value-p type) `(lambda (x) (equal x ,type)))
563
(defloop predicate-names/lambdas (types M)
564
(for ((type in types)) (collect (predicate-name/lambda type M))))
569
(defun dlistify (alist)
570
(declare (xargs :guard (alistp alist)))
571
(list-up-lists (strip-cars alist) (strip-cdrs alist)))
573
(defun polypred-instantiated-pred-alist (ppred->tname-map new-types wrld)
574
(b* ((M (append (table-alist 'tvar-metadata-table wrld) new-types (table-alist 'type-metadata-table wrld)))
575
(inst-preds (predicate-names (strip-cdrs ppred->tname-map) M)))
576
(pairlis$ (strip-cars ppred->tname-map) inst-preds)))
578
(defun functional-instantiation-list (ppred->tname-map tvar-sigma new-types kwd-alist wrld)
579
(b* ((M (append (table-alist 'tvar-metadata-table wrld) new-types (table-alist 'type-metadata-table wrld)))
581
(predicate-names/lambdas (acl2::sublis-var-lst *tvar-typename-alist* (strip-cars tvar-sigma)) M)
582
(predicate-names/lambdas (strip-cdrs tvar-sigma) M)))
584
(A2 (polypred-instantiated-pred-alist ppred->tname-map new-types wrld))
585
(ans (union-alist2 A2 A1)) ;A2 overrides A1
586
(ctx 'functional-instantiation-alist)
587
(- (cw? (and (or t (get1 :verbose kwd-alist t))
588
(not (alist-equiv ans (union-alist2 A1 A2))))
589
"~|Defdata/Warning:: ~x0 - tvar-sigma ~x1 entries differ from ppred-instpred-map ~x2" ctx A1 A2))
591
(dlistify (remove-duplicates-equal ans))))
593
(defun polypred-typename-map (tvar-sigma derived-pred->poly-texp-map new-types wrld)
594
(b* ((ppred->texp-map (subst-vals derived-pred->poly-texp-map tvar-sigma))
595
(M (append new-types (table-alist 'type-metadata-table wrld))))
596
(pairlis$ (strip-cars ppred->texp-map)
597
(find-type-names1 (strip-cdrs ppred->texp-map) M))))
599
(defloop filter-proper-symbols (xs)
600
(for ((x in xs)) (append (and (proper-symbolp x) (list x)))))
603
(defun psig-templ-instantiation-ev-user (tname tvar-sigma templ derived-pred->poly-texp-map new-types kwd-alist wrld)
604
"For given tvar-sigma, find functional instantiation and return instantiated templ"
605
(b* ((ppred->tname-map (polypred-typename-map tvar-sigma derived-pred->poly-texp-map new-types wrld))
606
; remove signatures that have no match
607
(templ (remove-exprs-with-fns templ (undefined-preds ppred->tname-map)))
609
(fun-inst-dlist (functional-instantiation-list (remove-undefined ppred->tname-map) tvar-sigma new-types kwd-alist wrld))
611
(pred (predicate-name tname (append new-types (table-alist 'type-metadata-table wrld))))
612
(disabled (remove-eq pred (append (filter-proper-symbols (strip-cadrs fun-inst-dlist)) (get1 :disabled kwd-alist))))
613
(enabled (and pred (list pred))) ;TODO.check later
614
(splice-alist `((_ENABLED-RUNES_ . ,enabled) (_DISABLED-RUNES_ . ,disabled) (_FUN-INST-ALIST_ . ,fun-inst-dlist)))
615
(ppred-inst-pred-alist (polypred-instantiated-pred-alist ppred->tname-map new-types wrld))
616
(atom-alist (acons '_PRED_ pred ppred-inst-pred-alist))
617
(str-alist (acons "_PRED_" (symbol-name pred) '())))
618
(template-subst templ
621
:splice-alist splice-alist
622
:atom-alist atom-alist
627
(defattach (psig-templ-instantiation-ev psig-templ-instantiation-ev-user) :skip-checks t)
630
(defloop psig-templ-instantiation-events (ps templ derived-pred->poly-texp-map new-types kwd-alist wrld)
631
(for ((p in ps)) (append (psig-templ-instantiation-ev (car p) (cdr p) templ derived-pred->poly-texp-map new-types kwd-alist wrld))))
633
; (n-ret-type (parse-top-texp '* return-type1 ctx wrld))
634
; (p-ret-type (untrans-texp '* n-ret-type ctx wrld))
637
(defconst *map-all-to-a* (pairlis$ *allowed-type-vars*
638
(make-list (len *allowed-type-vars*) :initial-element ':a)))
641
(defun simplify-prop-comb-texp (pdef)
642
(cond ((atom pdef) pdef)
643
((possible-constant-value-p pdef) pdef)
644
((member-eq (car pdef) '(or and oneof anyof))
645
(b* ((rest (remove-duplicates-equal (simplify-prop-comb-texps (cdr pdef)))))
646
(if (consp (cdr rest))
649
(t (cons (car pdef) (simplify-prop-comb-texps (cdr pdef))))))
650
(defun simplify-prop-comb-texps (texps)
653
(cons (simplify-prop-comb-texp (car texps))
654
(simplify-prop-comb-texps (cdr texps)))))
658
(defun find-match (ptype pdef)
659
(b* ((pdef (remove-names pdef))
660
((mv yes sigma) (one-way-unify ptype pdef))
661
((when yes) (mv t sigma)))
663
(if (eq (car ptype) 'LISTOF)
664
(b* (((mv yes sigma) (one-way-unify ptype (simplify-prop-comb-texp (acl2::sublis-var *map-all-to-a* pdef))))
665
((unless yes) (mv yes sigma))
666
(val (cdr (car sigma))) ;the lone :a mapped value
667
(tvars (all-vars pdef))
668
(sigma (pairlis$ tvars (make-list (len tvars) :initial-element val))))
672
(defun find-matches1 (ptype M)
675
(b* (((cons tname al) (car M))
676
(pdef (get1 :prettyified-def al))
677
((unless pdef) (find-matches1 ptype (cdr M))) ;skip types with NIL prettyified-def
678
((mv yes sigma) (find-match ptype pdef)))
680
(cons (cons tname sigma) (find-matches1 ptype (cdr M)))
681
(find-matches1 ptype (cdr M))))))
683
(defun find-matches (ptype wrld)
684
(find-matches1 ptype (table-alist 'type-metadata-table wrld)))
686
(defun find/make-type-name (ptexp M)
687
(if (and (proper-symbolp ptexp)
690
(to-symbol ptexp "DEFDATA")))
692
(defloop find/make-type-names (ptexps M)
693
(for ((ptexp in ptexps)) (collect (find/make-type-name ptexp M))))
695
(defun find/make-predicate-name (tname M)
696
(or (predicate-name tname M) (make-predicate-symbol tname (symbol-package-name tname))))
698
(defloop find/make-predicate-names (tnames M)
699
(for ((tname in tnames)) (collect (find/make-predicate-name tname M))))
701
(defun instantiate-poly-sig-events-for-current-types (as rtype templ kwd-alist wrld)
702
"limited/linear instantiation of poly signatures for all current types of same shape"
703
(declare (ignorable rtype))
704
(b* ((atype (pick-dominant-poly-type-expr (append as (list rtype)))) ;[2014-11-25 Tue] Dont ignore return type here.
705
((when (null atype)) nil) ;msg has been already shown
706
((when (symbolp atype)) nil) ;TODO.generalize restrict free/single-variable matches.
707
(tname-IA-alst (find-matches atype wrld)) ;get type -> (alistof tvar pred) mapping
708
(M (append (table-alist 'tvar-metadata-table wrld)
709
(table-alist 'type-metadata-table wrld)))
710
(arg-tnames (find/make-type-names (remove-names-lst as) M))
711
(arg-preds (find/make-predicate-names arg-tnames M))
712
(ret-tname (find/make-type-name (remove-names rtype) M))
713
(ret-pred (find/make-predicate-name ret-tname M))
714
(derived-pred->poly-texp-map (cons (cons ret-pred rtype) (pairlis$ arg-preds as)))
716
(psig-templ-instantiation-events tname-IA-alst templ derived-pred->poly-texp-map '() kwd-alist wrld)))
718
(defloop untrans-top-texps (nms nexps)
719
(for ((nm in nms) (nexp in nexps)) (collect (untrans-top-texp nm nexp '()))))
721
(defun make-sig-defthm-body (name arg-types ret-type kwd-alist wrld)
722
(b* ((M (append (table-alist 'tvar-metadata-table wrld)
723
(table-alist 'type-metadata-table wrld)))
724
(arg-tnames (find/make-type-names (remove-names-lst arg-types) M))
725
(arg-preds (find/make-predicate-names arg-tnames M))
726
(ret-tname (find/make-type-name (remove-names ret-type) M))
727
(ret-pred (find/make-predicate-name ret-tname M))
730
(x1--xk (numbered-vars 'ACL2S::X (len arg-preds)))
731
(dependent-hyps (get1 :satisfies kwd-alist)) ;they should only use x1, x2 etc
732
(hyps (append (list-up-lists arg-preds x1--xk) dependent-hyps))
733
(psig-defthm-body `(IMPLIES (AND . ,hyps)
734
,(list ret-pred (cons name x1--xk)))))
738
(defun sig-events1 (name arg-types ret-type kwd-alist ctx wrld)
739
(b* ((arg-type-list1 (acl2::sublis-var-lst *tvar-typename-alist* arg-types))
740
(return-type1 (acl2::sublis-var *tvar-typename-alist* ret-type)) ;instead of *allowed-type-var->named-type-binding*
741
(arity (len arg-types))
743
(stars (make-list arity :initial-element '*))
744
(n-arg-types (parse-top-texps stars arg-type-list1 ctx wrld))
745
(n-ret-type (parse-top-texp '* return-type1 (list '*) ctx wrld))
746
(p-arg-types (untrans-top-texps stars n-arg-types))
747
(p-ret-type (untrans-top-texp '* n-ret-type '()))
749
(psig-name (s+ name "-POLYMORPHIC-SIG"))
750
(psig-defthm-body (make-sig-defthm-body name p-arg-types p-ret-type kwd-alist wrld))
751
(poly-inst-template `((DEFTHM ,(s+ name "-_PRED_-SIG")
753
:hints (("Goal" :in-theory (e/d (_ENABLED-RUNES_) (,name _DISABLED-RUNES_))
754
:use ((:functional-instance ,psig-name
755
_fun-inst-alist_)))))))
756
; (- (cw "args: ~x0 ret: ~x1 derived-pred->poly-texp-map: ~x2 templ: ~x3" p-arg-types p-ret-type derived-pred->poly-texp-map poly-inst-template))
759
`(,@(make-sig-tvar-support-events (cons p-ret-type p-arg-types) ctx wrld)
761
(DEFTHM ,psig-name ;restriction: only one sig per function possible!
763
:hints ,(or (get1 :hints kwd-alist) `(("Goal" :in-theory (enable ,name))))
764
:rule-classes ,(get1 :rule-classes kwd-alist '(:rewrite)))
766
; for functional instantiating of future types of same shape
767
,@(register-poly-sig-events name p-arg-types p-ret-type poly-inst-template wrld)
769
; functionally instantiate all current types of same shape
770
,@(instantiate-poly-sig-events-for-current-types p-arg-types p-ret-type
775
(defun sig-events (parsed wrld)
776
(b* (((list name arg-types ret-type kwd-alist) parsed)
777
(testing-enabledp (get1 :testing-enabled kwd-alist nil))
778
;; dont even call acl2s-defaults if cgen/top is not included. This
779
;; allows defdata/sig to be used independently of cgen
780
(local-testing-downgraded-form (and testing-enabledp
781
'((LOCAL (ACL2S::ACL2S-DEFAULTS :SET ACL2S::TESTING-ENABLED :naive))))))
783
`(WITH-OUTPUT :on (acl2::summary acl2::error)
784
:SUMMARY (ACL2::FORM)
787
,@local-testing-downgraded-form
788
,@(sig-events1 name arg-types ret-type kwd-alist 'sig wrld)))))
792
(defmacro sig (&rest args)
793
(b* ((verbose (let ((lst (member :verbose args)))
794
(and lst (cadr lst)))))
795
`(with-output ,@(and (not verbose) '(:off :all))
799
(sig-events (parse-sig ',args 'sig (w state)) (w state))))))