-
Notifications
You must be signed in to change notification settings - Fork 273
Expand file tree
/
Copy pathExternal.agda
More file actions
60 lines (45 loc) · 2.04 KB
/
Copy pathExternal.agda
File metadata and controls
60 lines (45 loc) · 2.04 KB
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
------------------------------------------------------------------------
-- The Agda standard library
--
-- How to use reflection to call external functions.
--
-- IMPORTANT: In order for this file to type-check you will need to add
-- a line `/usr/bin/expr` to your `~/.agda/executables` file. See the
-- section on Reflection in the Agda user manual for more details.
------------------------------------------------------------------------
{-# OPTIONS --without-K --allow-exec #-}
module README.Reflection.External where
open import Data.List.Base using ([]; _∷_)
open import Data.String.Base using (String; _++_)
open import Relation.Binary.PropositionalEquality
-- All the commands needed to make an external system call are included
-- in `Reflection.External`.
open import Reflection.External
using (CmdSpec; runCmd)
-- The most important one is `CmdSpec` ("command specification")
-- which allows ones to specify the external command being called, its
-- arguments and the contents of stdin.
-- Here we define a simple command spec that takes two numbers and
-- uses the Unix `expr` command to add the two together.
add : String → String → CmdSpec
add x y = record
{ name = "expr"
; args = x ∷ "+" ∷ y ∷ []
; input = ""
}
-- The command can then be run using the `runCmd` macro. If no error
-- occured then by default the macro returns the result of `stdout`.
-- Otherwise the macro will terminate with a type error.
test : runCmd (add "1" "2") ≡ "3\n"
test = refl
-- If you are running a command that you know might be ill-formed
-- and result in an error then can use `unsafeRunCmd` instead that
-- returns a `Result` object containing the exit code and the contents
-- of both `stdout` and `stderr`.
open import Reflection.External
using (unsafeRunCmd; result; exitFailure)
error = "/usr/bin/expr: non-integer argument\n"
test2 : unsafeRunCmd (add "a" "b") ≡ result (exitFailure 2) "" error
test2 = refl
-- For a more advanced use-case where SMT solvers are invoked from
-- Agda, see Schmitty (https://github.com/wenkokke/schmitty)