Filtering...

fty-list

books/centaur/fty/fty-list
other
(in-package "FTY")
other
(include-book "database")
other
(include-book "fty-parseutils")
other
(include-book "std/lists/list-defuns" :dir :system)
other
(program)
other
(defconst *flexlist-keywords*
  '(:pred :fix :equiv :count :elt-type :non-emptyp :measure :measure-debug :xvar :true-listp :elementp-of-nil :cheap :parents :short :long :no-count :prepwork :post-pred-events :post-fix-events :post-events :enable-rules :verbosep))
other
(define parse-flexlist
  (x xvar
    our-fixtypes
    fixtypes
    state)
  (b* (((cons name args) x) ((unless (symbolp name)) (raise "Malformed flexlist: ~x0: name must be a symbol"
          x))
      ((mv pre-/// post-///) (split-/// name args))
      ((mv kwd-alist rest) (extract-keywords name
          *flexlist-keywords*
          pre-///
          nil))
      (kwd-alist (append kwd-alist
          (table-alist 'deflist-defaults
            (w state))))
      ((when rest) (raise "Malformed flexlist: ~x0: after kind should be a keyword/value list."
          name))
      (elt-type (getarg :elt-type nil kwd-alist))
      ((unless (and (symbolp elt-type) elt-type)) (raise "Bad flexlist ~x0: Element type must be a symbol"
          name))
      ((mv elt-type
         elt-fix
         elt-equiv
         recp) (get-pred/fix/equiv (getarg :elt-type nil kwd-alist)
          our-fixtypes
          fixtypes))
      (pred (getarg! :pred (intern-in-package-of-symbol (cat (symbol-name name) "-P")
            name)
          kwd-alist))
      (fix (getarg! :fix (intern-in-package-of-symbol (cat (symbol-name name) "-FIX")
            name)
          kwd-alist))
      (equiv (getarg! :equiv (intern-in-package-of-symbol (cat (symbol-name name) "-EQUIV")
            name)
          kwd-alist))
      (non-emptyp (getarg :non-emptyp nil kwd-alist))
      (elementp-of-nil (getarg :elementp-of-nil :unknown kwd-alist))
      (cheap (getarg :cheap nil kwd-alist))
      (count (flextype-get-count-fn name kwd-alist))
      (xvar (or (getarg :xvar xvar kwd-alist)
          (car (find-symbols-named-x (getarg :measure nil kwd-alist)))
          (intern-in-package-of-symbol "X" name)))
      (measure (getarg! :measure `(acl2-count ,FTY::XVAR)
          kwd-alist))
      ((mv already-defined true-listp) (check-flexlist-already-defined pred
          kwd-alist
          our-fixtypes
          'deflist
          state))
      (fix-already-defined (check-flexlist-fix-already-defined fix
          kwd-alist
          our-fixtypes
          'deflist
          state)))
    (make-flexlist :name name
      :pred pred
      :fix fix
      :equiv equiv
      :count count
      :elt-type elt-type
      :elt-fix elt-fix
      :elt-equiv elt-equiv
      :true-listp true-listp
      :elementp-of-nil elementp-of-nil
      :cheap cheap
      :measure measure
      :non-emptyp non-emptyp
      :kwd-alist (if post-///
        (cons (cons :///-events post-///) kwd-alist)
        kwd-alist)
      :xvar xvar
      :recp recp
      :already-definedp already-defined
      :fix-already-definedp fix-already-defined)))
other
(define flexlist-fns
  (x)
  (b* (((flexlist x)))
    (list x.pred x.fix)))
other
(define flexlist-collect-fix/pred-pairs
  (x)
  (b* (((flexlist x)))
    (and x.elt-type
      x.elt-fix
      (list (cons x.elt-fix x.elt-type)))))
other
(define flexlist-predicate-def
  (x)
  (b* (((flexlist x)) (stdx (intern-in-package-of-symbol "X" x.pred)))
    `(,@(IF FTY::X.ALREADY-DEFINEDP
      '(PROGN)
      `(FTY::DEFINE ,FTY::X.PRED (,FTY::X.XVAR) :PARENTS NIL :PROGN T :MEASURE
        ,FTY::X.MEASURE
        ,@(AND (FTY::GETARG :MEASURE-DEBUG NIL FTY::X.KWD-ALIST)
               `(:MEASURE-DEBUG T))
        ,(IF FTY::X.NON-EMPTYP
             `(AND (CONSP ,FTY::X.XVAR) (,FTY::X.ELT-TYPE (CAR ,FTY::X.XVAR))
                   (LET ((,FTY::X.XVAR (CDR ,FTY::X.XVAR)))
                     (IF (ATOM ,FTY::X.XVAR)
                         ,(IF FTY::X.TRUE-LISTP
                              `(EQ ,FTY::X.XVAR NIL)
                              T)
                         (,FTY::X.PRED ,FTY::X.XVAR))))
             `(IF (ATOM ,FTY::X.XVAR)
                  ,(IF FTY::X.TRUE-LISTP
                       `(EQ ,FTY::X.XVAR NIL)
                       T)
                  (AND (,FTY::X.ELT-TYPE (CAR ,FTY::X.XVAR))
                       (,FTY::X.PRED (CDR ,FTY::X.XVAR)))))
        ///)) (local (in-theory (disable ,FTY::X.PRED)))
      (deflist ,FTY::X.PRED
        (,FTY::STDX)
        :parents (,FTY::X.NAME)
        (,FTY::X.ELT-TYPE ,FTY::STDX)
        :already-definedp t
        ,@(AND (NOT (EQ FTY::X.ELEMENTP-OF-NIL :UNKNOWN))
       `(:ELEMENTP-OF-NIL ,FTY::X.ELEMENTP-OF-NIL))
        :true-listp ,FTY::X.TRUE-LISTP
        :non-emptyp ,FTY::X.NON-EMPTYP
        :cheap ,FTY::X.CHEAP))))
other
(define flexlist-fix-def
  (x flagp)
  (b* (((flexlist x)))
    (if x.fix-already-definedp
      '(progn)
      `(define ,FTY::X.FIX
        ((,FTY::X.XVAR ,FTY::X.PRED))
        :parents (,FTY::X.NAME)
        :short ,(FTY::CAT "@(call " (XDOC::FULL-ESCAPE-SYMBOL FTY::X.FIX)
  ") is a usual @(see fty::fty) list fixing function.")
        :long ,(FTY::CAT "<p>In the logic, we apply @(see? "
  (XDOC::FULL-ESCAPE-SYMBOL FTY::X.ELT-FIX)
  ") to each member of the x.  In the execution, none of
                    that is actually necessary and this is just an inlined
                    identity function.</p>")
        :measure ,FTY::X.MEASURE
        ,@(AND (FTY::GETARG :MEASURE-DEBUG NIL FTY::X.KWD-ALIST) `(:MEASURE-DEBUG T))
        ,@(AND FTY::FLAGP `(:FLAG ,FTY::X.NAME))
        :returns (newx ,FTY::X.PRED
          :hints (,@(AND (NOT FTY::FLAGP) `(("goal" :INDUCT (,FTY::X.FIX ,FTY::X.XVAR)))) '(:in-theory (disable ,FTY::X.FIX ,FTY::X.PRED)
              :expand ((,FTY::X.FIX ,FTY::X.XVAR) (:free (a b) (,FTY::X.PRED (cons a b)))
                (,FTY::X.PRED ,FTY::X.XVAR)
                (,FTY::X.PRED nil)))))
        :verify-guards nil
        :progn t
        :inline t
        (mbe :logic ,(IF FTY::X.NON-EMPTYP
     `(IF (CONSP (CDR ,FTY::X.XVAR))
          (CONS (,FTY::X.ELT-FIX (CAR ,FTY::X.XVAR))
                (,FTY::X.FIX (CDR ,FTY::X.XVAR)))
          (CONS (,FTY::X.ELT-FIX (CAR ,FTY::X.XVAR))
                ,(IF FTY::X.TRUE-LISTP
                     NIL
                     `(CDR ,FTY::X.XVAR))))
     `(IF (ATOM ,FTY::X.XVAR)
          ,(IF FTY::X.TRUE-LISTP
               NIL
               FTY::X.XVAR)
          (CONS (,FTY::X.ELT-FIX (CAR ,FTY::X.XVAR))
                (,FTY::X.FIX (CDR ,FTY::X.XVAR)))))
          :exec ,FTY::X.XVAR)
        ///))))
other
(define flexlist-fix-postevents
  (x)
  (b* (((flexlist x)) (stdx (intern-in-package-of-symbol "X" x.pred))
      (stda (intern-in-package-of-symbol "A" x.pred))
      (consp-of-foo-fix (intern-in-package-of-symbol (cat "CONSP-OF-" (symbol-name x.fix))
          x.fix))
      (consp-cdr-of-foo-fix (intern-in-package-of-symbol (cat "CONSP-CDR-OF-" (symbol-name x.fix))
          x.fix))
      (car-of-foo-fix (intern-in-package-of-symbol (cat "CAR-OF-" (symbol-name x.fix))
          x.fix))
      (foo-fix-under-iff (intern-in-package-of-symbol (cat (symbol-name x.fix) "-UNDER-IFF")
          x.fix))
      (foo-fix-of-cons (intern-in-package-of-symbol (cat (symbol-name x.fix) "-OF-CONS")
          x.fix))
      (len-of-foo-fix (intern-in-package-of-symbol (cat "LEN-OF-" (symbol-name x.fix))
          x.fix))
      (foo-fix-of-append (intern-in-package-of-symbol (cat (symbol-name x.fix) "-OF-APPEND")
          x.fix))
      (foo-fix-of-repeat (intern-in-package-of-symbol (cat (symbol-name x.fix) "-OF-REPEAT")
          x.fix))
      (nth-of-foo-fix (intern-in-package-of-symbol (cat "NTH-OF-" (symbol-name x.fix))
          x.fix))
      (list-equiv-refines-foo-equiv (intern-in-package-of-symbol (cat "LIST-EQUIV-REFINES-" (symbol-name x.equiv))
          x.equiv))
      (foo-equiv-implies-foo-equiv-append-1 (intern-in-package-of-symbol (cat (symbol-name x.equiv)
            "-IMPLIES-"
            (symbol-name x.equiv)
            "-APPEND-1")
          x.equiv))
      (foo-equiv-implies-foo-equiv-append-2 (intern-in-package-of-symbol (cat (symbol-name x.equiv)
            "-IMPLIES-"
            (symbol-name x.equiv)
            "-APPEND-2")
          x.equiv)))
    `((deffixcong ,FTY::X.EQUIV
       ,FTY::X.ELT-EQUIV
       (car x)
       x
       :pkg ,FTY::X.EQUIV
       :hints (("goal" :expand ((,FTY::X.FIX x))
          :in-theory (enable default-car)))) (deffixcong ,FTY::X.EQUIV
        ,FTY::X.EQUIV
        (cdr x)
        x
        :pkg ,FTY::X.EQUIV
        :hints (("goal" :expand ((,FTY::X.FIX x) ,@(AND FTY::X.NON-EMPTYP `((,FTY::X.FIX (CDR FTY::X)))))
           ,@(AND FTY::X.NON-EMPTYP '(:IN-THEORY (FTY::ENABLE FTY::DEFAULT-CAR))))))
      (deffixcong ,FTY::X.ELT-EQUIV
        ,FTY::X.EQUIV
        (cons x y)
        x
        :pkg ,FTY::X.EQUIV
        :hints (("goal" :expand ((:free (a b) (,FTY::X.FIX (cons a b)))))))
      ,@(AND (NOT FTY::X.NON-EMPTYP)
       `((FTY::DEFFIXCONG ,FTY::X.EQUIV ,FTY::X.EQUIV (CONS FTY::X FTY::Y)
          FTY::Y :PKG ,FTY::X.EQUIV :HINTS
          (("goal" :EXPAND
            ((:FREE (FTY::A FTY::B) (,FTY::X.FIX (CONS FTY::A FTY::B)))))))))
      (defthm ,FTY::CONSP-OF-FOO-FIX
        ,(IF FTY::X.NON-EMPTYP
     `(CONSP (,FTY::X.FIX FTY::X))
     `(EQUAL (CONSP (,FTY::X.FIX FTY::X)) (CONSP FTY::X)))
        :hints (("goal" :expand ((,FTY::X.FIX x)))))
      ,@(AND FTY::X.NON-EMPTYP
       `((FTY::DEFTHM ,FTY::CONSP-CDR-OF-FOO-FIX
          (EQUAL (CONSP (CDR (,FTY::X.FIX FTY::X))) (CONSP (CDR FTY::X)))
          :HINTS (("goal" :EXPAND ((,FTY::X.FIX FTY::X)))))
         (FTY::DEFTHM ,FTY::CAR-OF-FOO-FIX
          (EQUAL (CAR (,FTY::X.FIX FTY::X)) (,FTY::X.ELT-FIX (CAR FTY::X)))
          :HINTS (("goal" :EXPAND ((,FTY::X.FIX FTY::X)))))))
      ,@(AND (OR FTY::X.TRUE-LISTP FTY::X.NON-EMPTYP)
       `((FTY::DEFTHM ,FTY::FOO-FIX-UNDER-IFF
          ,(IF FTY::X.NON-EMPTYP
               `(,FTY::X.FIX FTY::X)
               `(FTY::IFF (,FTY::X.FIX FTY::X) (CONSP FTY::X)))
          :HINTS (("goal" :EXPAND ((,FTY::X.FIX FTY::X)))))))
      (defthm ,FTY::FOO-FIX-OF-CONS
        (equal (,FTY::X.FIX (cons ,FTY::STDA ,FTY::STDX))
          (cons (,FTY::X.ELT-FIX ,FTY::STDA)
            ,(IF FTY::X.NON-EMPTYP
     (IF FTY::X.TRUE-LISTP
         `(AND (CONSP ,FTY::STDX) (,FTY::X.FIX ,FTY::STDX))
         `(IF (CONSP ,FTY::STDX)
              (,FTY::X.FIX ,FTY::STDX)
              ,FTY::STDX))
     `(,FTY::X.FIX ,FTY::STDX))))
        :hints (("goal" :expand ((:free (a b) (,FTY::X.FIX (cons a b)))))))
      (defthm ,FTY::LEN-OF-FOO-FIX
        (equal (len (,FTY::X.FIX x))
          ,(IF FTY::X.NON-EMPTYP
     `(MAX 1 (FTY::LEN FTY::X))
     `(FTY::LEN FTY::X)))
        :hints (("goal" :induct (len x)
           :expand ((,FTY::X.FIX x))
           :in-theory (enable len))))
      ,@(AND (NOT FTY::X.NON-EMPTYP)
       `((FTY::DEFTHM ,FTY::FOO-FIX-OF-APPEND
          (EQUAL (,FTY::X.FIX (APPEND STD::A STD::B))
                 (APPEND (,FTY::X.FIX STD::A) (,FTY::X.FIX STD::B)))
          :HINTS
          (("goal" :INDUCT (APPEND STD::A STD::B) :EXPAND
            ((,FTY::X.FIX STD::A)
             (:FREE (FTY::A FTY::B) (,FTY::X.FIX (CONS FTY::A FTY::B)))
             (,FTY::X.FIX NIL) (:FREE (FTY::B) (APPEND STD::A FTY::B))
             (:FREE (FTY::B) (APPEND NIL FTY::B))
             (:FREE (FTY::A FTY::B FTY::C)
              (APPEND (CONS FTY::A FTY::B) FTY::C)))
            :IN-THEORY (FTY::ENABLE (:I APPEND)))))))
      ,@(AND (NOT FTY::X.NON-EMPTYP)
       `((FTY::DEFTHM ,FTY::FOO-FIX-OF-REPEAT
          (EQUAL (,FTY::X.FIX (FTY::REPEAT FTY::N FTY::X))
                 (FTY::REPEAT FTY::N (,FTY::X.ELT-FIX FTY::X)))
          :HINTS
          (("goal" :INDUCT (FTY::REPEAT FTY::N FTY::X) :EXPAND
            ((FTY::REPEAT FTY::N FTY::X)
             (FTY::REPEAT FTY::N (,FTY::X.ELT-FIX FTY::X))
             (:FREE (FTY::A FTY::B) (,FTY::X.FIX (CONS FTY::A FTY::B))))
            :IN-THEORY (FTY::ENABLE (:I FTY::REPEAT)))))))
      ,@(AND FTY::X.TRUE-LISTP (NOT FTY::X.NON-EMPTYP)
       `((FTY::DEFTHM ,FTY::LIST-EQUIV-REFINES-FOO-EQUIV
          (FTY::IMPLIES (FTY::LIST-EQUIV FTY::X FTY::Y)
           (,FTY::X.EQUIV FTY::X FTY::Y))
          :HINTS
          (("Goal" :INDUCT (FAST-LIST-EQUIV FTY::X FTY::Y) :IN-THEORY
            (FTY::ENABLE ,FTY::X.FIX FAST-LIST-EQUIV LIST-EQUIV TRUE-LIST-FIX)
            :EXPAND
            ((TRUE-LIST-FIX FTY::X) (TRUE-LIST-FIX FTY::Y) (,FTY::X.FIX FTY::X)
             (,FTY::X.FIX FTY::Y))))
          :RULE-CLASSES :REFINEMENT)))
      ,@(AND (NOT FTY::X.NON-EMPTYP)
       `((FTY::DEFTHM ,FTY::NTH-OF-FOO-FIX
          (EQUAL (NTH FTY::N (,FTY::X.FIX FTY::X))
                 (IF (< (FTY::NFIX FTY::N) (FTY::LEN FTY::X))
                     (,FTY::X.ELT-FIX (NTH FTY::N FTY::X))
                     NIL))
          :HINTS
          (("goal" :INDUCT (NTH FTY::N FTY::X) :EXPAND ((,FTY::X.FIX FTY::X))
            :IN-THEORY (FTY::ENABLE NTH FTY::LEN FTY::NFIX))))
         (FTY::DEFTHM ,FTY::FOO-EQUIV-IMPLIES-FOO-EQUIV-APPEND-1
          (FTY::IMPLIES (,FTY::X.EQUIV FTY::X FTY::X-EQUIV)
           (,FTY::X.EQUIV (APPEND FTY::X FTY::Y) (APPEND FTY::X-EQUIV FTY::Y)))
          :RULE-CLASSES (:CONGRUENCE) :HINTS
          (("goal" :IN-THEORY (FTY::ENABLE ,FTY::X.EQUIV ,FTY::X.FIX APPEND)
            :INDUCT (APPEND FTY::X FTY::Y))))
         (FTY::DEFTHM ,FTY::FOO-EQUIV-IMPLIES-FOO-EQUIV-APPEND-2
          (FTY::IMPLIES (,FTY::X.EQUIV FTY::Y FTY::Y-EQUIV)
           (,FTY::X.EQUIV (APPEND FTY::X FTY::Y) (APPEND FTY::X FTY::Y-EQUIV)))
          :RULE-CLASSES (:CONGRUENCE) :HINTS
          (("goal" :IN-THEORY (FTY::ENABLE ,FTY::X.EQUIV ,FTY::X.FIX APPEND)
            :INDUCT (APPEND FTY::X FTY::Y))))
         (FTY::DEFCONG ,FTY::X.EQUIV ,FTY::X.EQUIV (NTHCDR FTY::N FTY::L) 2
          :HINTS
          (("goal" :IN-THEORY (FTY::ENABLE ,FTY::X.EQUIV ,FTY::X.FIX NTHCDR)
            :INDUCT T :EXPAND
            ((,FTY::X.FIX FTY::L) (,FTY::X.FIX FTY::L-EQUIV)))))
         (FTY::DEFCONG ,FTY::X.EQUIV ,FTY::X.EQUIV (FTY::TAKE FTY::N FTY::L) 2
          :HINTS
          (("goal" :IN-THEORY
            (FTY::ENABLE ,FTY::X.EQUIV ,FTY::X.FIX FTY::TAKE FTY::CONS-EQUAL
             FTY::DEFAULT-CAR)
            :INDUCT T :EXPAND
            ((,FTY::X.FIX FTY::L) (,FTY::X.FIX FTY::L-EQUIV))))))))))
other
(define flexlist-fix-when-pred-thm
  (x flagp)
  (b* (((flexlist x)) (foo-fix-when-foo-p (intern-in-package-of-symbol (cat (symbol-name x.fix)
            "-WHEN-"
            (symbol-name x.pred))
          x.fix)))
    `(defthm ,FTY::FOO-FIX-WHEN-FOO-P
      (implies (,FTY::X.PRED ,FTY::X.XVAR)
        (equal (,FTY::X.FIX ,FTY::X.XVAR) ,FTY::X.XVAR))
      :hints (,@(AND (NOT FTY::FLAGP) `(("goal" :INDUCT (,FTY::X.FIX ,FTY::X.XVAR)))) '(:expand ((,FTY::X.PRED ,FTY::X.XVAR) (,FTY::X.FIX ,FTY::X.XVAR))
          :in-theory (disable ,FTY::X.FIX ,FTY::X.PRED))) . ,(AND FTY::FLAGP `(:FLAG ,FTY::X.NAME)))))
flexlist-countfunction
(defun flexlist-count
  (x types)
  (b* (((flexlist x)) ((unless x.count) nil)
      (eltcount (flextypes-find-count-for-pred x.elt-type
          types)))
    `((define ,FTY::X.COUNT
       ((,FTY::X.XVAR ,FTY::X.PRED))
       :returns (count natp
         :rule-classes :type-prescription :hints ('(:expand (,FTY::X.COUNT ,FTY::X.XVAR)
            :in-theory (disable ,FTY::X.COUNT))))
       :measure (let ((,FTY::X.XVAR (,FTY::X.FIX ,FTY::X.XVAR)))
         ,FTY::X.MEASURE)
       ,@(AND (FTY::GETARG :MEASURE-DEBUG NIL FTY::X.KWD-ALIST) `(:MEASURE-DEBUG T))
       :verify-guards nil
       :progn t
       ,(IF FTY::X.NON-EMPTYP
     `(IF (CONSP (CDR ,FTY::X.XVAR))
          (+ 1 ,@(AND FTY::ELTCOUNT `((,FTY::ELTCOUNT (CAR ,FTY::X.XVAR))))
             (,FTY::X.COUNT (CDR ,FTY::X.XVAR)))
          (+ 1 ,@(AND FTY::ELTCOUNT `((,FTY::ELTCOUNT (CAR ,FTY::X.XVAR))))))
     `(IF (ATOM ,FTY::X.XVAR)
          1
          (+ 1 ,@(AND FTY::ELTCOUNT `((,FTY::ELTCOUNT (CAR ,FTY::X.XVAR))))
             (,FTY::X.COUNT (CDR ,FTY::X.XVAR)))))))))
flexlist-count-post-eventsfunction
(defun flexlist-count-post-events
  (x types)
  (b* (((flexlist x)) ((unless x.count) nil)
      (eltcount (flextypes-find-count-for-pred x.elt-type
          types))
      (foo-count-of-cons (intern-in-package-of-symbol (cat (symbol-name x.count) "-OF-CONS")
          x.count))
      (foo-count-of-cdr (intern-in-package-of-symbol (cat (symbol-name x.count) "-OF-CDR")
          x.count))
      (foo-count-of-car (intern-in-package-of-symbol (cat (symbol-name eltcount) "-OF-CAR")
          x.count)))
    `((defthm ,FTY::FOO-COUNT-OF-CONS
       ,(LET ((FTY::BODY
        `(> (,FTY::X.COUNT (CONS FTY::A FTY::B))
            ,(IF FTY::ELTCOUNT
                 `(+ (,FTY::ELTCOUNT FTY::A) (,FTY::X.COUNT FTY::B))
                 `(,FTY::X.COUNT FTY::B)))))
   (IF FTY::X.NON-EMPTYP
       `(FTY::IMPLIES (CONSP FTY::B) ,FTY::BODY)
       FTY::BODY))
       :hints (("goal" :expand ((:free (a b) (,FTY::X.COUNT (cons a b))))))
       :rule-classes :linear) ,@(AND FTY::ELTCOUNT
       `((FTY::DEFTHM ,FTY::FOO-COUNT-OF-CAR
          (FTY::IMPLIES
           ,(IF FTY::X.NON-EMPTYP
                T
                `(CONSP ,FTY::X.XVAR))
           (< (,FTY::ELTCOUNT (CAR ,FTY::X.XVAR))
              (,FTY::X.COUNT ,FTY::X.XVAR)))
          ,@(AND FTY::X.NON-EMPTYP
                 `(:HINTS (("goal" :EXPAND ((,FTY::X.COUNT ,FTY::X.XVAR))))))
          :RULE-CLASSES :LINEAR)))
      (defthm ,FTY::FOO-COUNT-OF-CDR
        (implies ,(IF FTY::X.NON-EMPTYP
     `(CONSP (CDR ,FTY::X.XVAR))
     `(CONSP ,FTY::X.XVAR))
          (< (,FTY::X.COUNT (cdr ,FTY::X.XVAR))
            (,FTY::X.COUNT ,FTY::X.XVAR)))
        :rule-classes :linear))))