File: External.agda

package info (click to toggle)
agda-stdlib 2.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,196 kB
  • sloc: haskell: 375; makefile: 32; sh: 28; lisp: 1
file content (60 lines) | stat: -rw-r--r-- 2,098 bytes parent folder | download
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 --cubical-compatible --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)