File: with-timeout.lisp

package info (click to toggle)
acl2 8.6%2Bdfsg-3
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 1,138,276 kB
  • sloc: lisp: 17,818,294; java: 125,359; python: 28,122; javascript: 23,458; cpp: 18,851; ansic: 11,569; perl: 7,678; xml: 5,591; sh: 3,978; makefile: 3,840; ruby: 2,633; yacc: 1,126; ml: 763; awk: 295; csh: 233; lex: 197; php: 178; tcl: 49; asm: 23; haskell: 17
file content (96 lines) | stat: -rw-r--r-- 3,110 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#|$ACL2s-Preamble$;
(begin-book t :ttags ((:acl2s-timeout)))
;$ACL2s-Preamble$|#

;Author: Harsh Raju Chamarthi
;Acknowledgements: Matt Kaufmann provided significant help.

(in-package "ACL2")

; We exclude Lisps not handled by macro with-timeout-raw in file
; with-timeout-raw.lsp (and perhaps there are other such), as follows.

; cert_param: (non-cmucl)
; cert_param: (non-lispworks)
; cert_param: (non-allegro)
; cert_param: (non-gcl)

(include-book "xdoc/top" :dir :system)
(defxdoc with-timeout
  :parents (acl2::cgen acl2::miscellaneous) ; the latter helps ACL2-only :doc
  :short  "Evaluate form with a timeout (in seconds)"
  :long
  "<p>Evaluate form with a timeout in seconds. </p>

  <p>The general form is:
  @({with-timeout duration body timeout-form})
  </p>

  <p>
  @('duration') can be any rational value.  A duration of 0 seconds disables
  the timeout mechanism, i.e its a no-op. Suppose it is not, and @('duration')
  seconds elapse during evaluation of <tt>body</tt> then the evaluation is aborted
  and the value of @('timeout-form') is returned; in the normal case the value
  of <tt>body</tt> is returned.
  </p>
  <p> The signature of <tt>body</tt> and <tt>timeout-form</tt> should be the same.  </p>

  <h3>Advanced Notes:</h3>
  <p>
  This form should be called either at the top-level or in
  an environment where state is available and <tt>body</tt> has
  no free variables other than state.
  If the timeout-form is a long running computation,
  then the purpose of with-timeout is defeated.
  </p>

  <code>
    Usage:
    (with-timeout 5 (fibonacci 40) :timed-out)
    :doc with-timeout
  </code>
"
  )

(defttag :acl2s-timeout)

(progn!
 (set-raw-mode t)
 (load (concatenate 'string (cbd) "with-timeout-raw.lsp")))

(defmacro-last with-timeout-aux)

;; Defined this way to be compatible with make-event.
;; If time is 0, we set a timeout of 2^20 seconds ~ 12 days
(defmacro with-time-limit (time form)
  `(with-prover-time-limit
    (if (equal ,time 0) (expt 2 20) ,time)
    ,form))

(defmacro with-timeout (duration form timeout-form)
"can only be called at top-level, that too only forms that are allowed
to be evaluated inside a function body. To eval defthm, use
with-timeout-ev instead"
`(if (equal 0 ,duration) ;if 0 then timeout is disabled
     ,form
   (top-level (with-timeout1 ,duration ,form ,timeout-form))))


;the following is for internal use only. I use it in timing out
;top-level-test? form, where i manually make a function body
;corresponding to the top-level-test?-fn, this way I dont have to
;worry about capturing free variables

(defmacro with-timeout1 (duration form timeout-form)
"can only be used inside a function body, and if form has
free variables other than state, then manually make a function
which takes those free variables as arguments and at the calling
context, pass the arguments, binding the free variables.
See top-level-test? macro for an example"
`(if (equal 0 ,duration) ;if 0 then timeout is disabled
    ,form
  (with-timeout-aux '(,duration ,timeout-form) ,form)))

(defttag nil) ; optional (books end with this implicitly)