-;; (define (verify-cases data-layouts annotated-program)
-
-;; (define allowed-match-ast-types
-;; '((Int . (int-literal var))
-;; (Bool . (bool-literal var))
-;; (String . (string-literal var))))
+(define (constructor? data-layouts x)
+ (and (eqv? (ast-type x) 'var)
+ (assoc x (flat-map cdr data-layouts))))
+
+(define (all-cases data-layouts type)
+ (let ([sums (assoc type data-layouts)])
+ (if sums
+ (flat-map (lambda (sum)
+ (let* ([sum-name (car sum)]
+ [products (cdr sum)]
+ [product-cases (map (lambda (y) (all-cases data-layouts y)) products)])
+ (if (null? product-cases)
+ (list sum-name) ; singletons aren't enclosed in a list [(foo x) 42] vs [foo 42]
+ (apply combinations (cons (list sum-name) product-cases)))))
+ (cdr sums))
+ '(:binding))))
+
+ ; does a cover b
+(define (case-covers? data-layouts a b)
+ (let ([a-binding? (and (eqv? (ast-type a) 'var) (not (constructor? data-layouts a)))])
+ (if (eqv? ':binding b)
+ a-binding?
+ (if a-binding?
+ #t
+ (if (eqv? (ast-type b) 'var)
+ (eqv? b a)
+ (all (map (lambda (p q)
+ (case-covers? data-layouts p q))
+ (cdr a) (cdr b))))))))
+
+(define (verify-cases data-layouts annotated-program)