Skip to content

Commit 52bccd9

Browse files
committed
improve handling of ellipses in premises when checking modeless judgment forms
1 parent 9b006c3 commit 52bccd9

File tree

3 files changed

+95
-6
lines changed

3 files changed

+95
-6
lines changed

redex-lib/redex/private/matcher.rkt

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -621,19 +621,35 @@ See match-a-pattern.rkt for more details
621621
(loop (cdr matches) (cons merged acc))
622622
(loop (cdr matches) acc)))])))
623623

624-
(define (combine-bindings-lists bindings1 bindings2 lang-α-equal?)
624+
(define (combine-bindings-lists bindings1 bindings1-to-dup
625+
bindings2 bindings2-to-dup
626+
lang-α-equal?)
625627
(define all-combinations/f
626628
(for*/list ([binding1 (in-list bindings1)]
627629
[binding2 (in-list bindings2)])
630+
(define table1 (bindings-table binding1))
631+
(define table2 (bindings-table binding2))
628632
(merge-multiples/remove/bindings
629-
(make-bindings (append (bindings-table binding1)
630-
(bindings-table binding2)))
633+
(make-bindings (append (fill-out-duplicates table1 bindings1-to-dup binding2)
634+
(fill-out-duplicates table2 bindings2-to-dup binding1)))
631635
lang-α-equal?)))
632636
(define all-combinations (filter values all-combinations/f))
633637
(cond
634638
[(null? all-combinations) #f]
635639
[else all-combinations]))
636640

641+
(define (fill-out-duplicates table to-duplicate table-with-lengths)
642+
(for/list ([a-bind (in-list table)])
643+
(define n (bind-name a-bind))
644+
(cond
645+
[(member n to-duplicate)
646+
(define exp (bind-exp a-bind))
647+
(define how-many-times (length (lookup-binding table-with-lengths n)))
648+
(bind n
649+
(for/list ([i (in-range how-many-times)])
650+
exp))]
651+
[else a-bind])))
652+
637653
;; merge-multiples/remove : bindings (exp exp -> boolean) -> (union #f bindings)
638654
;; returns #f if all duplicate bindings don't bind the same thing
639655
;; returns a new bindings
@@ -2110,7 +2126,9 @@ See match-a-pattern.rkt for more details
21102126
compiled-lang?))
21112127
[combine-bindings-lists
21122128
(-> (listof bindings?)
2129+
(listof symbol?)
21132130
(listof bindings?)
2131+
(listof symbol?)
21142132
(procedure-arity-includes/c 2)
21152133
(or/c #f (non-empty-listof bindings?)))])
21162134
(provide compiled-pattern?

redex-lib/redex/private/modeless-jf.rkt

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,38 @@
169169
(lookup-binding bnds 'modeless-prem-names) ...)
170170
body)))))
171171

172+
(define (get-id-depths ids)
173+
(define ht (make-hash))
174+
(for ([id (in-list (syntax->list ids))])
175+
(define-values (sym depth) (get-id-depth id))
176+
(hash-set! ht sym depth))
177+
ht)
178+
(define (get-id-depth stx)
179+
(let loop ([stx stx]
180+
[n 0])
181+
(syntax-case stx ()
182+
[(more ell)
183+
(is-ellipsis? #'ell)
184+
(loop #'more (+ n 1))]
185+
[_ (values (syntax-e stx) n)])))
186+
(define premise-id-depths (get-id-depths #'(modeless-prem-names/ellipses ...)))
187+
(define conc-id-depths (get-id-depths #'(conc-names/ellipses ...)))
188+
(define (get-ids-to-dup our-id-depths others-id-depths)
189+
(for/list ([(id depth) (in-hash our-id-depths)]
190+
#:when (< depth
191+
(hash-ref others-id-depths id -inf.0)))
192+
id))
193+
172194
#`(begin
173195
conc-syncheck-exp
174196
modeless-jf-name-only-prems-syncheck-exp
175197
modeless-prems-syncheck-exp
176198
(build-modeless-jf-clause
177199
lang
178200
`conc
201+
'(#,@(get-ids-to-dup conc-id-depths premise-id-depths))
179202
`modeless-prem
203+
'(#,@(get-ids-to-dup premise-id-depths conc-id-depths))
180204
`modeless-jf-name-only-prem
181205
'(#,@premise-repeat-names)
182206
#,other-conditions
@@ -205,10 +229,14 @@
205229
(list)
206230
(list #`(cons #f (list #,@noname-clauses))))))))
207231

208-
(define (build-modeless-jf-clause lang conc modeless-prem modeless-jf-name-only-prem
232+
(define (build-modeless-jf-clause lang conc conc-ids-to-duplicate
233+
modeless-prem modeless-prem-ids-to-duplicate
234+
modeless-jf-name-only-prem
209235
premise-repeat-names other-conditions funcs)
210236
(modeless-jf-clause (compile-pattern lang conc #f)
237+
conc-ids-to-duplicate
211238
(compile-pattern lang modeless-prem #f)
239+
modeless-prem-ids-to-duplicate
212240
(compile-pattern lang modeless-jf-name-only-prem #f)
213241
premise-repeat-names other-conditions funcs))
214242

@@ -276,7 +304,9 @@
276304
(match candidates
277305
[`() (fail)]
278306
[(cons (modeless-jf-clause conclusion-compiled-pattern
307+
conclusion-ids-to-duplicate
279308
premises-compiled-pattern
309+
premise-ids-to-duplicate
280310
premises-jf-name-only-compiled-pattern
281311
premises-repeat-names
282312
other-conditions
@@ -297,10 +327,15 @@
297327
(cons (symbol->string (car t)) (cdr t))))
298328
(define sub-derivations-mtch (match-pattern premises-compiled-pattern
299329
sub-derivations-arguments-term-list))
330+
(define sub-derivation-bindings (and sub-derivations-mtch
331+
(map mtch-bindings sub-derivations-mtch)))
332+
(define conc-bindings (map mtch-bindings conc-mtch))
300333
(define conc+sub-bindings
301334
(and sub-derivations-mtch
302-
(combine-bindings-lists (map mtch-bindings conc-mtch)
303-
(map mtch-bindings sub-derivations-mtch)
335+
(combine-bindings-lists sub-derivation-bindings
336+
premise-ids-to-duplicate
337+
conc-bindings
338+
conclusion-ids-to-duplicate
304339
(λ (a b) (alpha-equivalent? lang a b)))))
305340
(cond
306341
[conc+sub-bindings
@@ -332,6 +367,7 @@
332367
(fail-to-next-candidate)])]
333368
[else (fail-to-next-candidate)])]))
334369

370+
335371
(define (modeless-jf-process-other-conditions lang
336372
sub-derivations
337373
conc+sub-bindings
@@ -398,13 +434,15 @@
398434
[_ #f])]))])))
399435

400436
(struct modeless-jf-clause (conclusion-compiled-pattern
437+
conclusion-ids-to-duplicate
401438

402439
;; pattern with all of the premises
403440
;; strung together in a list, but where
404441
;; the names of the judgment forms are
405442
;; strings instead of symbols (so that they
406443
;; don't accidentally run into non-terminals, etc)
407444
premises-compiled-pattern
445+
premises-ids-to-duplicate
408446

409447
;; pattern with all of the premises jf-names strung
410448
;; together, but with `any` for all of the arguments

redex-test/redex/tests/tl-judgment-form.rkt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,4 +1627,37 @@
16271627
(list)))
16281628
#f))
16291629

1630+
(let ()
1631+
(define-language L)
1632+
1633+
(define-judgment-form L
1634+
1635+
[-------------- "nat"
1636+
(⊢ natural N)]
1637+
1638+
[-------------- "bool"
1639+
(⊢ boolean B)]
1640+
1641+
[(⊢ any_many any_dup) ...
1642+
---------------------------- "all-same"
1643+
(⊢ (any_many ...) any_dup)])
1644+
1645+
(test (judgment-holds
1646+
1647+
(derivation
1648+
'(⊢ (0) N)
1649+
"all-same"
1650+
(list (derivation '(⊢ 0 N) "nat" (list)))))
1651+
#t)
1652+
1653+
(test (judgment-holds
1654+
1655+
(derivation
1656+
'(⊢ (0 1 2) N)
1657+
"all-same"
1658+
(list (derivation '(⊢ 0 N) "nat" (list))
1659+
(derivation '(⊢ 1 N) "nat" (list))
1660+
(derivation '(⊢ 2 N) "nat" (list)))))
1661+
#t))
1662+
16301663
(print-tests-passed 'tl-judgment-form.rkt)

0 commit comments

Comments
 (0)