You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: NEWS.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,9 +3,9 @@ This file contains a summary of important user-visible changes.
3
3
ethos 0.1.2 prerelease
4
4
======================
5
5
6
+
- Drops support for `:var` and `:implicit` as *term* attributes. The recommended way of introducing function symbols with named arguments is via the command `declare-parameterized-const`, which now permits the parameter annotations `:requires`, `:implicit`, and `:opaque`. The parameters of a parameterized constants are no longer assumed to be implicit, and are explicit by default. The `:implicit` attribute can be used on all parameters to recover the previous behavior.
6
7
- Change the execution semantics when a program takes an unevalated term as an argument. In particular, we do not call user provided programs and oracles when at least argument could not be evaluated. This change was made to make errors more intuitive. Note this changes the semantics of programs that previously relied on being called on unevaluated terms.
7
8
- User programs, user oracles, and builtin operators that are unapplied are now considered unevaluated. This makes the type checker more strict and disallows passing them as arguments to other programs, which previously led to undefined behavior.
8
-
- Changes the interface of `declare-parameterized-const`. In particular, the parameters of a parameterized constants are no longer assumed to be implicit, and are explicit by default. The `:implicit` attribute can be used on all parameters to recover the previous behavior. Other attributes such as `:opaque` and `:requires` can be used on parameters to this command.
9
9
- Remove support for the explicit parameter annotation `eo::_`, which was used to provide annotations for implicit arguments to parameterized constants.
10
10
- Changed the semantics of pairwise and chainable operators for a single argument, which now reduces to the neutral element of the combining operator instead of a parse error.
11
11
- The operator `eo::typeof` now fails to evaluate if the type of the given term is not ground.
@@ -16,7 +16,7 @@ ethos 0.1.2 prerelease
16
16
17
17
- Added the option `--stats-all` to track the number of times side conditions are invoked.
18
18
- The option `--print-let` has been renamed to `--print-dag` and is now enabled by default. The printer is changed to use `eo::define` instead of `let`.
19
-
- Ethos now explicitly forbids `:var`,`:implicit`, and `:opaque` on return types.
19
+
- Ethos now explicitly forbids the`:opaque` annotation on return types.
20
20
- The option `--binder-fresh`, which specified for fresh variables to be constructed when parsing binders, has been removed.
Copy file name to clipboardExpand all lines: user_manual.md
+42-57Lines changed: 42 additions & 57 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -216,57 +216,63 @@ In particular:
216
216
217
217
This indicates the checker to compare the type it computed for the term `(not true)`, with the specified type `Bool`. An error will be thrown if the two types are not identical.
218
218
219
-
### The :var and :implicit annotations
219
+
### Declaring Parameterized Constants
220
220
221
-
The Eunoia language uses the SMT-LIB version 3.0 attributes `:var <symbol>` and `:implicit` in term annotations, for naming arguments of functions and specifying that they are implicit.
221
+
The Eunoia language uses the command `declare-parameterized-const`, for declaring constants that have (possibly) dependent types.
222
+
In particular, this command allows naming arguments of functions and specifying that they are implicit.
(declare-parameterized-const eq ((T Type)) (-> T T Bool))
226
234
(define P ((x Int) (y Int)) (eq Int x y))
227
235
```
228
236
229
237
The above example declares a predicate symbol `eq` whose first argument is a type, that is given name `T`. It then expects two terms of type `T` and returns a `Bool`. In the definition of `P`, `eq` is applied to two variables, with type `Int` explicitly provided.
230
238
231
-
In contrast, the example below declares a predicate `=` where the type of the arguments is implicit (this corresponds to the SMT-LIB standard definition of `=`). In the definition of `P`, the type `Int` of the arguments is not provided.
239
+
In contrast, the example below declares a predicate `=` where the type of the arguments is implicit (this corresponds to the SMT-LIB standard definition of `=`). An implicit argument for a parameterized constant can be given by the annotation `:implicit`. In the definition of `P`, the type `Int` of the arguments is not provided.
232
240
233
241
```smt
234
242
(declare-type Int ())
235
-
(declare-const = (-> (! Type :var T :implicit) T T Bool))
243
+
(declare-parameterized-const = ((T Type :implicit)) (-> T T Bool))
236
244
(define P ((x Int) (y Int)) (= x y))
237
245
```
238
246
239
247
In general, an argument can be made implicit if its value can be inferred from the type of later arguments.
240
248
241
-
Return types cannot be marked `:implicit` or `:var` or a type error will be immediately reported.
242
-
243
249
We call `T` in the above definitions a _parameter_. The free parameters of the return type of an expression should be contained in at least one non-implicit argument. In particular, the following declaration is malformed, since the return type of `f` cannot be inferred from its arguments:
244
250
245
251
```smt
246
252
(declare-type Int ())
247
-
(declare-const f (-> (! Type :var T :implicit) Int T))
253
+
(declare-const f ((T Type :implicit)) (-> Int T))
248
254
```
249
255
250
-
> __Note:__ Internally, `(! T :var t)` is syntax sugar for the type `(Quote t)` where `t` is a parameter of type`T` and `Quote` is a distinguished type of kind `(-> (! Type :var U) U Type)`. When type checking applications of functions of type `(-> (Quote t) S)`, the parameter `t` is bound to the argument the function is applied to.
256
+
> __Note:__ Internally, parameters `(t T)` in the command `declare-parameterized-const` are handled specially in the type system. In particular `(declare-parameterized-const foo ((T Type)) T)` defines `foo` to be of "quote arrow" type, `(~> T T)`, where the argument to `foo` is bound to `T`, e.g. `(foo Int)` binds `T` to `Int` and thus has type `Int`. Technical details of the type system can be found at the end of this manual.
251
257
252
-
> __Note:__ Internally, `(! T :implicit)` drops `T` from the list of arguments of the function type we are defining.
258
+
> __Note:__ Internally, `(t T :implicit)` drops `t` from the list of arguments of the function type we are defining.
253
259
254
260
### The :requires annotation
255
261
256
262
Arguments to functions can also be annotated with the attribute `:requires (<term> <term>)` to denote a equality condition that is required for applications of the term to type check.
257
263
258
264
```smt
259
265
(declare-type Int ())
260
-
(declare-const BitVec (-> (! Int :var w :requires ((eo::is_neg w) false)) Type))
266
+
(declare-parameterized-const BitVec ((w Int :requires ((eo::is_neg w) false))) Type)
261
267
```
262
268
The above declares the integer type `Int` and a bitvector type constructor `BitVec` that expects a _non-negative integer_`w`.
263
269
In detail, the first argument of `BitVec` is supposed to be an `Int` value and is named `w` via the `:var` attribute.
264
270
The second annotation indicates that the term `(eo::is_neg w)` must evaluate to `false` at type checking type.
265
271
Symbol `eo::is_neg` denotes a builtin function that returns `true` if its argument is a negative numeral, and returns false otherwise (for details, see [computation](#computation)).
266
272
<!-- This needs discussion, what is the input type of `eo::is_neg`? How can `eo::is_neg` accept a value of a user-defined type `Int` given that it is builtin? -->
267
273
268
-
> __Note:__ Internally, `(! T :requires (t s))` is syntax sugar for the type term `(eo::requires t s T)` where `eo::requires` is an operator that evaluates to its third argument if and only if its first two arguments are _computationally_ equivalent (details on this operator are given in [computation](#computation)).
269
-
Furthermore, the function type `(-> (eo::requires t s T) S)` is treated as `(-> T (eo::requires t s S))`. Ethos rewrites all types of the former form to the latter.
274
+
> __Note:__ Internally, a parameter `(t T :requires (s r))` is syntax sugar for the type term `(eo::requires s r T)` where `eo::requires` is an operator that evaluates to its third argument if and only if its first two arguments are _computationally_ equivalent (details on this operator are given in [computation](#computation)).
275
+
Furthermore, the function type `(-> (eo::requires s r T) S)` is treated as `(-> T (eo::requires s r S))`. Ethos rewrites all types of the former form to the latter.
270
276
271
277
<aname="opaque"></a>
272
278
@@ -278,8 +284,8 @@ An example of this annotation is the following:
278
284
279
285
```smt
280
286
(declare-type Array (Type Type))
281
-
(declare-const @array_diff
282
-
(-> (! Type :var T :implicit) (! Type :var U :implicit)
287
+
(declare-parameterized-const @array_diff ((T Type :implicit) (U Type :implicit))
288
+
(->
283
289
(! (Array T U) :opaque)
284
290
(! (Array T U) :opaque)
285
291
T))
@@ -430,20 +436,7 @@ that references the free constant `re.all`.
430
436
431
437
However, when using `declare-const`, the nil terminator of an associative operator cannot depend on the parameters of the type of that function.
432
438
For example, say we wish to declare bitvector or (`bvor` in SMT-LIB), where its nil terminator is the bitvector zero.
433
-
A possible declaration is the following:
434
-
435
-
```smt
436
-
(declare-const bvor
437
-
(-> (! Int :var m :implicit) (BitVec m) (BitVec m) (BitVec m))
438
-
:right-assoc-nil #b0000
439
-
)
440
-
```
441
-
442
-
Above, note that `m` was not in scope when defining the nil terminator of this operator,
443
-
and thus we have hardcoded the nil terminator to be a bitvector of width `4`.
444
-
This definition is clearly limited, as applications of this operator will fail to type check if `m` is not `4`.
445
-
However,
446
-
the command `declare-parameterized-const` can be used to define a version of `bvor` whose nil terminator depends on `m`,
439
+
The command `declare-parameterized-const` can be used to define a version of `bvor` whose nil terminator depends on `m`,
447
440
which we will describe later in [param-constants](#param-constants).
448
441
449
442
#### List
@@ -524,7 +517,7 @@ For example, `(>= x)` is equivalent to `true`.
524
517
```smt
525
518
(declare-type Int ())
526
519
(declare-const and (-> Bool Bool Bool) :right-assoc)
527
-
(declare-const distinct (-> (! Type :var T :implicit) T T Bool) :pairwise and)
520
+
(declare-parameterized-const distinct ((T Type :implicit)) (-> T T Bool) :pairwise and)
528
521
(define P ((x Int) (y Int) (z Int)) (distinct x y z))
529
522
```
530
523
@@ -546,7 +539,7 @@ For example, `(distinct x)` is equivalent to `true`.
546
539
(declare-type Int ())
547
540
(declare-type @List ())
548
541
(declare-const @nil @List)
549
-
(declare-const @cons (-> (! Type :var T :implicit) T @List @List)
542
+
(declare-parameterized-const @cons ((T Type :implicit)) (-> T @List @List)
@@ -943,9 +936,8 @@ for the term `or` applied to arguments `a,b`.
943
936
(declare-consts <numeral> Int)
944
937
(declare-type BitVec (Int))
945
938
946
-
(declare-const concat (->
947
-
(! Int :var n :implicit)
948
-
(! Int :var m :implicit)
939
+
(declare-parameterized-const concat ((n Int :implicit) (m Int :implicit))
940
+
(->
949
941
(BitVec n)
950
942
(BitVec m)
951
943
(BitVec (eo::add n m))))
@@ -995,15 +987,10 @@ This means that when type checking the binary constant `#b0000`, its type prior
995
987
996
988
<aname="param-constants"></a>
997
989
998
-
## Parameterized constants
990
+
## Parameterized constants with Attributes
999
991
1000
992
Recall that in [assoc-nil](#assoc-nil), when using `declare-const` to define associative operators with nil terminators, it is not possible to have the nil terminator for that operator depend on its type parameters.
1001
-
In this section, we introduce a new command `declare-parameterized-const` which overcomes this limitation.
0 commit comments