Filtering...

run-script

books/tools/run-script

Included Books

other
(in-package "ACL2")
include-book
(include-book "xdoc/top" :dir :system)
other
(defxdoc run-script
  :parents (testing-utilities)
  :short "Run a script."
  :long "<p>@('Run-script') is a utility for testing evaluation of the forms in
 a given file, to check that the output is as expected.  The forms need not be
 embedded event forms (see @(see events)), and they need not all evaluate
 successfully; for example, a @(tsee thm) form may produce a failed proof
 attempt.</p>

 <p>General form:</p>

 @({
 (run-script NAME
             :inhibited-summary-types i-s-t  ; default '(time steps)
             :inhibit-output-lst      i-o-l  ; default '(proof-tree)
             :ld-error-action         action ; default ':continue
             )
 })

 <p>where the keyword arguments are evaluated.  For information on the keyword
 arguments, see @(tsee set-inhibited-summary-types), @(tsee
 set-inhibit-output-lst), and @(tsee ld-error-action).</p>

 <p>Example form:</p>

 @({
 (run-script "mini-proveall")
 })

 <p>When you call @('(run-script NAME)'), the forms in @('NAME-input.lsp')
 are evaluated and a transcript is written to @('NAME-log.out').
 Forms that are @(see command)s change the logical world.</p>

 <p>NOTE: The @(see time-tracker) utility is disabled by @('run-script').
 After a call of @('run-script'), you need to evaluate @('(time-tracker t)') if
 you want to return to the default behavior (where the time-tracker capability
 is enabled).  Similarly, printing of &lsquo;@('; Hons-Note')&rsquo; comments
 are suppressed by @('run-script') (more precisely: whenever @(see state)
 global @(''script-mode') has a non-@('nil') value).</p>

 <p>To use @('run-script') for regression testing, you will need
 to create three files in addition to the input file, as described below.
 For an example, see the files @('books/demos/mini-proveall-*.*') in
 the @(see community-books); there, @('NAME') is @('mini-proveall').</p>

 <ul>

 <li>@('NAME-input.lsp') &mdash; the file of forms to be evaluated</li>

 <li>@('NAME-book.acl2') &mdash; a file containing the following, where the
 indicated zero or more @(tsee include-book) forms are exactly those that are
 in @('NAME-input.lsp') (note that the form @('(ubu 1)') can perhaps be omitted
 but is needed in some cases, e.g., see
 @('books/projects/paco/books/proveall-book.acl2'))

 @({
 (include-book "tools/run-script" :dir :system)
 (run-script "NAME") ; optionally add keyword arguments
 (ubu 1)

 ; Help dependency scanner.
 #||
 (depends-on "NAME-log.txt")
 (depends-on "NAME-input.lsp")
 (include-book ...)
 (include-book ...)
 ...
 ||#
 })</li>

 <li>@('NAME-book.lisp') &mdash; a small file containing only these two forms:

 @({
 (in-package "ACL2")
 (assert-event
  (identical-files-p "NAME-log.txt" "NAME-log.out"))
 })</li>

 <li>@('NAME-log.txt') &mdash; the expected result from evaluating the forms in
 @('NAME-input.lsp')</li>

 </ul>

 <p>To create @('NAME-log.txt'), initially create it as the empty file (or,
 actually, create any file with that name).  Then run the test, for example
 using @('cert.pl') (see @(see build::cert.pl)) as follows.</p>

 @({
 <PATH_TO_books/build>/cert.pl -j 8 NAME-book
 })

 <p>Now inspect the generated file @('NAME-log.out').  When you are satisfied
 that it is as expected, move it to @('NAME-log.txt').  The @('cert.pl')
 command displayed above should now succeed.</p>

 <p>NOTE: If you fail to create file @('NAME-log.txt'), you will likely see an
 error message of the following form when you run @('cert.pl').</p>

 @({
 make: *** No rule to make target `NAME-log.txt', needed by `NAME-book.cert'.
 })

 <p>The solution is to create the missing file @('NAME-log.txt'), for example
 with the following shell command.</p>

 @({
 touch NAME-log.txt
 })

 <p><b>Remarks.</b></p>

 <ul>

 <li>Note for ACL2(r) users: The prompt is set by @('run-script') so that the
 usual "(r)" is not printed.</li>

 <li>If you want commands like @(':')@(tsee pe) to avoid printing event
 numbers, put the form @('(assign script-mode 'skip-ldd-n)') into your
 @('*-input.lsp') file.  See @(see community-book) file
 @('demos/floating-point-input.lsp') for an example.</li>

 <li>@('Run-script') always sets @(tsee gag-mode) to its default,
 @(':goals').</li>

 </ul>")
include-book
(include-book "xdoc/top" :dir :system)
include-book
(include-book "show-diff-lines")
diff-msgfunction
(defun diff-msg
  (file1 file2 s1 s2)
  (declare (type string file1 file2 s1 s2)
    (xargs :guard-hints (("Goal" :in-theory (disable length)))))
  (let* ((lines-before 5) (lines-after 5)
      (p (first-diff-position s1 s2)))
    (msg "Showing (up to) ~x0 lines before and ~x1 lines after the line where ~
          those files first differ.~|~%~
          ############### ~s2 ###############~|~
          ~s3~|~
          ############### ~s4 ###############~|~
          ~s5~|~
          ##################################################~|"
      lines-before
      lines-after
      file1
      (surrounding-lines s1 p lines-before lines-after)
      file2
      (surrounding-lines s2 p lines-before lines-after))))
identical-files-p-fnfunction
(defun identical-files-p-fn
  (file1 file2 state)
  (declare (xargs :stobjs state
      :guard (and (stringp file1) (stringp file2))))
  (let ((str1 (read-file-into-string file1)) (str2 (read-file-into-string file2))
      (ctx 'identical-files-p))
    (cond ((null str1) (er hard? ctx "File ~x0 is missing or unreadable." file1))
      ((null str2) (er hard? ctx "File ~x0 is missing or unreadable." file2))
      ((equal str1 str2) t)
      (t (er hard?
          ctx
          "Files ~x0 and ~x1 differ.~|~@2~|"
          file1
          file2
          (diff-msg file1 file2 str1 str2))))))
identical-files-pmacro
(defmacro identical-files-p
  (file1 file2)
  `(identical-files-p-fn ,FILE1 ,FILE2 state))
unset-waterfall-parallelismmacro
(defmacro unset-waterfall-parallelism
  nil
  '(state-global-let* ((inhibit-output-lst (cons 'observation (@ inhibit-output-lst))))
    (er-progn (set-waterfall-parallelism1 nil)
      (value :invisible))))
run-scriptmacro
(defmacro run-script
  (name &key
    (inhibited-summary-types ''(time steps))
    (inhibit-output-lst ''(proof-tree))
    (ld-error-action ':continue))
  (let ((input-file (concatenate 'string name "-input.lsp")) (output-file (concatenate 'string name "-log.out")))
    `(prog2$ (time-tracker nil)
      (pprogn (set-gag-mode :goals)
        (ld '((unset-waterfall-parallelism) (assign script-mode t)
            (set-ld-prompt t state)
            (set-inhibited-summary-types ,INHIBITED-SUMMARY-TYPES)
            (set-inhibit-output-lst ,INHIBIT-OUTPUT-LST) . ,INPUT-FILE)
          :ld-prompt nil
          :ld-verbose nil
          :ld-pre-eval-print t
          :ld-error-action ,LD-ERROR-ACTION
          :standard-co ,OUTPUT-FILE
          :proofs-co ,OUTPUT-FILE)))))