Filtering...

fixequiv

books/centaur/fty/fixequiv
other
(in-package "FTY")
other
(include-book "fixtype")
other
(include-book "std/util/formals" :dir :system)
other
(include-book "std/lists/mfc-utils" :dir :system)
other
(include-book "std/util/defines" :dir :system)
other
(program)
other
(set-state-ok t)
fixequiv-post-define-hookfunction
(defun fixequiv-post-define-hook
  (guts user-args state)
  (declare (xargs :mode :program :stobjs state))
  (b* (((defguts guts) guts))
    (cw "Fixequiv hook: automatic congruences for ~x0.~%"
      guts.name)
    (value `(deffixequiv ,FTY::GUTS.NAME . ,FTY::USER-ARGS))))
other
(add-post-define-hook :fix fixequiv-post-define-hook)
fixequivs->eventsfunction
(defun fixequivs->events
  (x)
  (if (atom x)
    nil
    (cons (fixequiv-events (car x))
      (fixequivs->events (cdr x)))))
find-formal-by-namefunction
(defun find-formal-by-name
  (varname formals)
  (if (atom formals)
    nil
    (if (eq (formal->name (car formals)) varname)
      (car formals)
      (find-formal-by-name varname (cdr formals)))))
other
(defconst *deffixequiv-keywords*
  '(:args :omit :hints :verbosep :skip-const-thm :skip-cong-thm))
fixequiv-type-from-guardfunction
(defun fixequiv-type-from-guard
  (guard wrld)
  (and (tuplep 2 guard)
    (let ((type1 (car guard)))
      (or (cdr (assoc type1
            (table-alist 'fixequiv-guard-type-overrides
              wrld)))
        type1))))
fixequiv-from-define-formalfunction
(defun fixequiv-from-define-formal
  (fn formal hints opts state)
  (b* (((formal fm) formal) (type (fixequiv-type-from-guard fm.guard
          (w state)))
      (stobjname (and (fgetprop fm.name 'stobj nil (w state))
          (congruent-stobj-rep fm.name (w state))))
      (type (or type stobjname))
      ((unless type) nil)
      (formals (fgetprop fn 'formals :none (w state)))
      (event (deffixequiv-basic-parse (cons fn formals)
          fm.name
          type
          `(:skip-ok t :hints ,FTY::HINTS . ,FTY::OPTS)
          state)))
    (and event (list event))))
fixequivs-from-define-formalsfunction
(defun fixequivs-from-define-formals
  (fn omit
    formals
    hints
    opts
    state)
  (if (atom formals)
    nil
    (append (and (not (member (formal->name (car formals)) omit))
        (fixequiv-from-define-formal fn
          (car formals)
          hints
          opts
          state))
      (fixequivs-from-define-formals fn
        omit
        (cdr formals)
        hints
        opts
        state))))
remove-keyfunction
(defun remove-key
  (key kwlist)
  (b* ((look (member key kwlist)) ((unless look) kwlist)
      (pre (take (- (len kwlist) (len look))
          kwlist)))
    (append pre (cddr look))))
fixequiv-from-explicit-argfunction
(defun fixequiv-from-explicit-arg
  (fn arg
    gutsformals
    formals
    hints
    global-opts
    state)
  (b* ((__function__ 'deffixequiv) ((mv var type/opts) (if (atom arg)
          (mv arg nil)
          (mv (car arg) (cdr arg))))
      ((mv type opts) (if (keywordp (car type/opts))
          (mv nil type/opts)
          (mv (car type/opts) (cdr type/opts))))
      (type (or type
          (b* ((formal (find-formal-by-name var gutsformals)) ((unless formal) (if gutsformals
                  (raise "~x0 is not a formal of function ~x1"
                    var
                    fn)
                  (raise "Can't derive argument types from ~x0 because it ~
                        wasn't created with DEFINE."
                    fn)))
              ((formal fm) formal)
              (type (or (fixequiv-type-from-guard fm.guard
                    (w state))
                  (and (fgetprop fm.name 'stobj nil (w state))
                    (congruent-stobj-rep fm.name (w state)))))
              ((unless type) (raise "Argument ~x0 of function ~x1 wasn't given a ~
                               (unary) type in its DEFINE declaration"
                  var
                  fn)))
            type)))
      (arg-hints (cadr (member :hints opts)))
      (opts-without-hints (remove-key :hints opts))
      (opts (append `(:hints ,(APPEND FTY::ARG-HINTS FTY::HINTS))
          opts-without-hints
          global-opts)))
    (deffixequiv-basic-parse (cons fn formals)
      var
      type
      opts
      state)))
set-fixequiv-guard-overridemacro
(defmacro set-fixequiv-guard-override
  (guard-fn type)
  `(table fixequiv-guard-type-overrides
    ',FTY::GUARD-FN
    ',TYPE))
fixequivs-from-explicit-argsfunction
(defun fixequivs-from-explicit-args
  (fn args
    gutsformals
    formals
    hints
    global-opts
    state)
  (if (atom args)
    nil
    (let ((event (fixequiv-from-explicit-arg fn
           (car args)
           gutsformals
           formals
           hints
           global-opts
           state)))
      (if event
        (cons event
          (fixequivs-from-explicit-args fn
            (cdr args)
            gutsformals
            formals
            hints
            global-opts
            state))
        (fixequivs-from-explicit-args fn
          (cdr args)
          gutsformals
          formals
          hints
          global-opts
          state)))))
deffixequiv-expand-hint-fnfunction
(defun deffixequiv-expand-hint-fn
  (fn stable-under-simplificationp
    id
    clause
    world)
  (b* ((forcing-roundp (not (eql 0 (access clause-id id :forcing-round)))) ((when forcing-roundp) nil)
      (pool-lst (access clause-id id :pool-lst))
      (top-levelp (not pool-lst))
      (single-inductionp (equal pool-lst '(1)))
      ((unless (or top-levelp single-inductionp)) nil)
      ((when (and top-levelp (recursivep fn t world))) `(:computed-hint-replacement t
          :induct (,FTY::FN . ,(FTY::FGETPROP FTY::FN 'FORMALS T FTY::WORLD))))
      ((unless stable-under-simplificationp) nil)
      (concl (car (last clause)))
      (hint (b* (((when (and (consp concl)
                (eq (car concl) 'not)
                (consp (second concl))
                (eq (car (second concl)) fn))) (list :expand (list (second concl)))) ((unless (and (consp concl) (eq (car concl) 'equal))) nil)
            (lhs (second concl))
            (rhs (third concl))
            (lhs-hint (if (and (consp lhs) (eq (car lhs) fn))
                (list lhs)
                nil))
            (rhs-hint (if (and (consp rhs) (eq (car rhs) fn))
                (list rhs)
                nil))
            ((unless (or lhs-hint rhs-hint)) nil))
          (list :expand (append lhs-hint rhs-hint))))
      ((unless hint) nil))
    (observation-cw 'deffixequiv
      "Giving expand hint ~x0.~%"
      hint)
    hint))
deffixequiv-expand-hintmacro
(defmacro deffixequiv-expand-hint
  (fn)
  `(deffixequiv-expand-hint-fn ',FTY::FN
    stable-under-simplificationp
    id
    clause
    world))
deffixequiv-default-hintsfunction
(defun deffixequiv-default-hints
  (fnname world)
  (let ((entry (cdr (assoc 'deffixequiv
           (table-alist 'default-hints-table world)))))
    (subst fnname 'fnname entry)))
set-deffixequiv-default-hintsmacro
(defmacro set-deffixequiv-default-hints
  (hint)
  `(table default-hints-table
    'deffixequiv
    ',FTY::HINT))
other
(set-deffixequiv-default-hints ((deffixequiv-expand-hint fnname)))
deffixequiv-fnfunction
(defun deffixequiv-fn
  (fn kw-args state)
  (b* ((__function__ 'deffixequiv) (world (w state))
      ((mv kwd-alist rest) (extract-keywords 'deffixequiv
          *deffixequiv-keywords*
          kw-args
          nil))
      ((when rest) (raise "Error: extra arguments: ~x0" rest))
      (guts-alist (get-define-guts-alist world))
      (guts (cdr (assoc fn guts-alist)))
      (gutsformals (and guts (defguts->formals guts)))
      (args (cdr (assoc :args kwd-alist)))
      (hints (if (assoc :hints kwd-alist)
          (cdr (assoc :hints kwd-alist))
          (deffixequiv-default-hints fn world)))
      ((when (and (not args) (not guts))) (raise "Deffixequiv requires either explicit types for the arguments ~
                to be considered, or for the function to have DEFINE info, ~
                which ~x0 does not."
          fn))
      (fn (if guts
          (defguts->name-fn guts)
          fn))
      (omit (cdr (assoc :omit kwd-alist)))
      (global-opts `(:skip-const-thm ,(CDR (ASSOC :SKIP-CONST-THM FTY::KWD-ALIST))
          :skip-cong-thm ,(CDR (ASSOC :SKIP-CONG-THM FTY::KWD-ALIST))))
      ((when (and args omit)) (raise "Why would you provide both :args and :omit?")))
    (if args
      (fixequivs-from-explicit-args fn
        args
        gutsformals
        (fgetprop fn 'formals :none (w state))
        hints
        global-opts
        state)
      (fixequivs-from-define-formals fn
        omit
        gutsformals
        hints
        global-opts
        state))))
deffixequivmacro
(defmacro deffixequiv
  (fn &rest keys)
  (b* ((verbosep (let ((lst (member :verbosep keys)))
         (and lst (cadr lst)))))
    `(with-output ,@(AND (NOT FTY::VERBOSEP) '(:OFF :ALL))
      :stack :push (make-event (cons 'progn
          (fixequivs->events (deffixequiv-fn ',FTY::FN ',FTY::KEYS state)))))))
other
(defconst *deffixequiv-mutual-keywords*
  '(:args :omit :verbosep :hints :no-induction-hint))
find-define-guts-by-fn/flag-namefunction
(defun find-define-guts-by-fn/flag-name
  (fn gutslist)
  (if (atom gutslist)
    nil
    (if (or (eq fn (defguts->name (car gutslist)))
        (eq fn (defguts->name-fn (car gutslist)))
        (eq fn
          (cdr (assoc :flag (defguts->kwd-alist (car gutslist))))))
      (car gutslist)
      (find-define-guts-by-fn/flag-name fn
        (cdr gutslist)))))
find-entry-by-fn/flag-namefunction
(defun find-entry-by-fn/flag-name
  (guts al)
  (b* (((defguts guts) guts))
    (or (assoc guts.name al)
      (assoc guts.name-fn al)
      (assoc (cdr (assoc :flag guts.kwd-alist)) al))))
args->varnamesfunction
(defun args->varnames
  (args)
  (if (atom args)
    nil
    (cons (if (atom (car args))
        (car args)
        (caar args))
      (args->varnames (cdr args)))))
keep-argsfunction
(defun keep-args
  (args keep-names)
  (if (atom args)
    nil
    (if (member (if (atom (car args))
          (car args)
          (caar args))
        keep-names)
      (cons (car args)
        (keep-args (cdr args) keep-names))
      (keep-args (cdr args) keep-names))))
mutual-fixequivs-from-explicit-argsfunction
(defun mutual-fixequivs-from-explicit-args
  (fn-args univ-args gutslist state)
  (b* (((when (atom gutslist)) nil) (guts (car gutslist))
      ((defguts guts) guts)
      (formal-names (formallist->names guts.formals))
      (fn-fn-args (cdr (find-entry-by-fn/flag-name guts fn-args)))
      (fn-univ-args (keep-args univ-args
          (set-difference-eq formal-names
            (args->varnames fn-fn-args))))
      (args (append fn-fn-args fn-univ-args))
      (fixequivs (fixequivs-from-explicit-args guts.name-fn
          args
          guts.formals
          formal-names
          nil
          nil
          state)))
    (cons (cons guts.name fixequivs)
      (mutual-fixequivs-from-explicit-args fn-args
        univ-args
        (cdr gutslist)
        state))))
mutual-fixequivs-from-definesfunction
(defun mutual-fixequivs-from-defines
  (fn-omit univ-omit gutslist state)
  (b* (((when (atom gutslist)) nil) ((defguts guts) (car gutslist))
      (omit-look (or (assoc guts.name fn-omit)
          (assoc guts.name-fn fn-omit)
          (assoc (cdr (assoc :flag guts.kwd-alist)) fn-omit)))
      (fixequivs (fixequivs-from-define-formals guts.name-fn
          (append univ-omit (cdr omit-look))
          guts.formals
          nil
          nil
          state)))
    (cons (cons guts.name fixequivs)
      (mutual-fixequivs-from-defines fn-omit
        univ-omit
        (cdr gutslist)
        state))))
fixequivs->fix-thms-with-flagsfunction
(defun fixequivs->fix-thms-with-flags
  (flag fixequivs)
  (if (atom fixequivs)
    nil
    (cons (append (fixequiv->fix-thm (car fixequivs))
        `(:flag ,FTY::FLAG))
      (fixequivs->fix-thms-with-flags flag
        (cdr fixequivs)))))
fn-mutual-fixequivs->inductive-fix-thmsfunction
(defun fn-mutual-fixequivs->inductive-fix-thms
  (fn fixequivs gutslist)
  (b* ((guts (find-define-guts-by-fn/flag-name fn
         gutslist)) ((unless guts) (er hard?
          'deffixequiv-mutual
          "function name not found?"))
      (flag (guts->flag guts)))
    (fixequivs->fix-thms-with-flags flag
      fixequivs)))
mutual-fixequivs->inductive-fix-thmsfunction
(defun mutual-fixequivs->inductive-fix-thms
  (fixequiv-al gutslist)
  (if (atom fixequiv-al)
    nil
    (append (fn-mutual-fixequivs->inductive-fix-thms (caar fixequiv-al)
        (cdar fixequiv-al)
        gutslist)
      (mutual-fixequivs->inductive-fix-thms (cdr fixequiv-al)
        gutslist))))
defgutslist->namesfunction
(defun defgutslist->names
  (x)
  (if (atom x)
    nil
    (cons (defguts->name (car x))
      (defgutslist->names (cdr x)))))
deffixequiv-mutual-default-default-hintfunction
(defun deffixequiv-mutual-default-default-hint
  (fnname id world)
  (let ((fns (recursivep fnname t world)))
    (and (eql 0 (access clause-id id :forcing-round))
      (equal '(1) (access clause-id id :pool-lst))
      `(:computed-hint-replacement ((and stable-under-simplificationp
           (expand-calls . ,FTY::FNS)))
        :in-theory (disable . ,FTY::FNS)))))
deffixequiv-mutual-default-hintsfunction
(defun deffixequiv-mutual-default-hints
  (fnname world)
  (let ((entry (cdr (assoc 'deffixequiv-mutual
           (table-alist 'default-hints-table world)))))
    (subst fnname 'fnname entry)))
set-deffixequiv-mutual-default-hintsmacro
(defmacro set-deffixequiv-mutual-default-hints
  (hint)
  `(table default-hints-table
    'deffixequiv-mutual
    ',FTY::HINT))
other
(set-deffixequiv-mutual-default-hints ((deffixequiv-mutual-default-default-hint 'fnname
     id
     world)))
mutual-fixequivs->fix-thmfunction
(defun mutual-fixequivs->fix-thm
  (fixequiv-al defines-entry
    kwd-alist
    world)
  (b* ((thm-macro (defines-guts->flag-defthm-macro defines-entry)) (gutslist (defines-guts->gutslist defines-entry))
      (fn1 (defguts->name-fn (car gutslist)))
      (hints-look (assoc :hints kwd-alist))
      (hints (if hints-look
          (cdr hints-look)
          (deffixequiv-mutual-default-hints fn1 world))))
    `(with-output :stack :pop (,FTY::THM-MACRO ,@(FTY::MUTUAL-FIXEQUIVS->INDUCTIVE-FIX-THMS FTY::FIXEQUIV-AL FTY::GUTSLIST)
        :hints ,FTY::HINTS
        :no-induction-hint ,(CDR (ASSOC :NO-INDUCTION-HINT FTY::KWD-ALIST))
        :skip-others t))))
fixequivs->const/cong-thmsfunction
(defun fixequivs->const/cong-thms
  (fixequivs)
  (if (atom fixequivs)
    nil
    (let* ((rest (fixequivs->const/cong-thms (cdr fixequivs))) (cong-thm (fixequiv->cong-thm (car fixequivs)))
        (const-thm (fixequiv->const-thm (car fixequivs)))
        (events (cons cong-thm rest)))
      (if const-thm
        (cons const-thm events)
        events))))
mutual-fixequivs->const/cong-thmsfunction
(defun mutual-fixequivs->const/cong-thms
  (fixequiv-al)
  (if (atom fixequiv-al)
    nil
    (append (fixequivs->const/cong-thms (cdar fixequiv-al))
      (mutual-fixequivs->const/cong-thms (cdr fixequiv-al)))))
get-atomsfunction
(defun get-atoms
  (x)
  (if (atom x)
    nil
    (if (atom (car x))
      (cons (car x) (get-atoms (cdr x)))
      (get-atoms (cdr x)))))
get-consesfunction
(defun get-conses
  (x)
  (if (atom x)
    nil
    (if (atom (car x))
      (get-conses (cdr x))
      (cons (car x) (get-conses (cdr x))))))
get-fn-argsfunction
(defun get-fn-args
  (args gutslist)
  (if (atom args)
    nil
    (if (and (consp (car args))
        (find-define-guts-by-fn/flag-name (caar args)
          gutslist))
      (cons (car args)
        (get-fn-args (cdr args) gutslist))
      (get-fn-args (cdr args) gutslist))))
get-nonfn-argsfunction
(defun get-nonfn-args
  (args gutslist)
  (if (atom args)
    nil
    (if (and (consp (car args))
        (find-define-guts-by-fn/flag-name (caar args)
          gutslist))
      (get-nonfn-args (cdr args) gutslist)
      (cons (car args)
        (get-nonfn-args (cdr args) gutslist)))))
deffixequiv-mutual-fnfunction
(defun deffixequiv-mutual-fn
  (name kw-args state)
  (b* ((__function__ 'deffixequiv-mutual) (world (w state))
      ((mv kwd-alist rest) (extract-keywords 'deffixequiv-mutual
          *deffixequiv-mutual-keywords*
          kw-args
          nil))
      ((when rest) (raise "Error: extra arguments: ~x0" rest))
      (defines-alist (get-defines-alist world))
      (defines-entry (cdr (assoc name defines-alist)))
      ((unless (and defines-entry
           (defines-guts->flag-defthm-macro defines-entry))) (raise "Deffixequiv-mutual is intended to work on mutual recursions ~
                created using DEFINES with a flag function.  You should give ~
                the name of the defines form, not the name of the function."))
      (args (cdr (assoc :args kwd-alist)))
      (omit (cdr (assoc :omit kwd-alist)))
      (gutslist (defines-guts->gutslist defines-entry))
      (univ-args (get-nonfn-args args gutslist))
      (fn-args (get-fn-args args gutslist))
      (univ-omit (get-atoms omit))
      (fn-omit (get-conses omit))
      ((when (and args omit)) (raise "Why would you provide both :args and :omit?"))
      (fns/fixequivs (if args
          (mutual-fixequivs-from-explicit-args fn-args
            univ-args
            gutslist
            state)
          (mutual-fixequivs-from-defines fn-omit
            univ-omit
            gutslist
            state))))
    (cons (mutual-fixequivs->fix-thm fns/fixequivs
        defines-entry
        kwd-alist
        world)
      (mutual-fixequivs->const/cong-thms fns/fixequivs))))
deffixequiv-mutualmacro
(defmacro deffixequiv-mutual
  (name &rest keys)
  (b* ((verbosep (let ((lst (member :verbosep keys)))
         (and lst (cadr lst)))))
    `(with-output ,@(AND (NOT FTY::VERBOSEP) '(:OFF :ALL))
      :stack :push (make-event (cons 'progn
          (deffixequiv-mutual-fn ',FTY::NAME
            ',FTY::KEYS
            state))))))