Skip to content

Commit 34f16e8

Browse files
Merge branch 'develop-theorem-typos'. Close #560.
**Description** The README in `copilot-theorem` includes several typos, such as _proportionnal_, _occurences_ and _latters_. Those typos should be corrected. **Type** - Bug: typo in documentation. **Additional context** None. **Requester** - Ikko Eltociear Ashimine and Ivan Perez **Method to check presence of bug** By visual inspection, potentially using a spell checker for help. The typos are mixed with technical words, to spell checkers cannot automatically tell us with 100% certainty whether all typos have been fixed. **Expected result** The README of `copilot-theorem` contains no typos. **Solution implemented** Use a spell checker to find and fix all typos in copilot-theorem, being careful with technical terms that are correct but spell checkers do not understand, such as _reification_. **Further notes** None.
2 parents 71dd870 + 2d7a06e commit 34f16e8

File tree

2 files changed

+77
-73
lines changed

2 files changed

+77
-73
lines changed

copilot-theorem/CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2025-01-25
2+
* Fix multiple typos in README. (#560)
3+
14
2025-01-07
25
* Version bump (4.2). (#577)
36
* Remove uses of Copilot.Core.Expr.UExpr.uExprType,uExprExpr. (#565)

copilot-theorem/README.md

Lines changed: 74 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
Highly automated proof techniques are a necessary step for the widespread
66
adoption of formal methods in the software industry. Moreover, it could provide
7-
a partial answer to one of its main issue which is scalability.
7+
a partial answer to one of its main issues, which is scalability.
88

99
*copilot-theorem* is a Copilot library aimed at checking automatically some safety
1010
properties on Copilot programs. It includes:
@@ -17,9 +17,9 @@ properties on Copilot programs. It includes:
1717
proving basic k-inductive properties and for pedagogical purposes.
1818

1919
* A prover producing native inputs for the *Kind2* model checker, developed at
20-
University of Iowa. The latter uses both the *k-induction algorithm* extended
21-
with *path compression* and *structural abstraction* [2] and the **IC3
22-
algorithm** with counterexample generalization based on *approximate
20+
the University of Iowa. The latter uses both the *k-induction algorithm*
21+
extended with *path compression* and *structural abstraction* [2] and the
22+
**IC3 algorithm** with counterexample generalization based on *approximate
2323
quantifier elimination* [3].
2424

2525
## A Tutorial
@@ -39,12 +39,12 @@ README.
3939
### First steps
4040

4141
*copilot-theorem* is aimed at checking **safety properties** on Copilot programs.
42-
Intuitively, a safety property is a property which express the idea that
42+
Intuitively, a safety property is a property that expresses the idea that
4343
*nothing bad can happen*. In particular, any invalid safety property can be
4444
disproved by a finite execution trace of the program called a
4545
**counterexample**. Safety properties are often opposed to **liveness**
4646
properties, which express the idea that *something good will eventually
47-
happen*. The latters are out of the scope of *copilot-theorem*.
47+
happen*. The latter is out of the scope of *copilot-theorem*.
4848

4949
Safety properties are simply expressed with standard boolean streams. In
5050
addition to triggers and observers declarations, it is possible to bind a
@@ -70,7 +70,7 @@ This function takes three arguments:
7070
* The name of the proposition we want to check.
7171
* A strategy to prove the proposition.
7272

73-
In this case the proposition is simple enough so that we can check it directly
73+
In this case, the proposition is simple enough so that we can check it directly
7474
by k-induction using `kind2Prover`. Therefore we can just write:
7575

7676
```haskell
@@ -79,14 +79,15 @@ main = do
7979
prove spec' "gt0" (tell [Check $ kind2Prover def])
8080
```
8181

82-
where `kind2Prover def` stands for the *Kind2 prover* with default
82+
where `kind2Prover def` stands for the *Kind2 prover* with the default
8383
configuration.
8484

8585
#### The Kind2 prover
8686

87-
The *Kind2* prover uses the model checker with the same name, from Iowa
88-
university. It translates the Copilot specification into a *modular transition
89-
system* (the Kind2 native format) and then calls the `kind2` executable.
87+
The *Kind2* prover uses the model checker with the same name, from the
88+
University of Iowa. It translates the Copilot specification into a *modular
89+
transition system* (the Kind2 native format) and then calls the `kind2`
90+
executable.
9091

9192
It is provided by the `Copilot.Theorem.Kind2` module, which exports a `kind2Prover
9293
:: Options -> Prover` where the `Options` type is defined as
@@ -117,7 +118,7 @@ Some examples are in the *examples* folder, including:
117118
### An introduction to SMT-based model checking
118119

119120
An introduction to the model-checking techniques used by *copilot-theorem* can be
120-
found in the `doc` folder of this repository. It consists in a self sufficient
121+
found in the `doc` folder of this repository. It consists of a self-sufficient
121122
set of slides. You can find some additional readings in the *References*
122123
section.
123124

@@ -216,16 +217,16 @@ process* [7] and so we have no way to keep them.
216217
#### Types
217218

218219
In these three formats, GADTs are used to statically ensure a part of the
219-
type-corectness of the specification, in the same spirit it is done in the
220-
other Copilot libraries. *copilot-theorem* handles only three types which are
221-
`Integer`, `Real` and `Bool` and which are handled by the SMTLib standard.
220+
type-correctness of the specification, in the same spirit as in
221+
other Copilot libraries. *copilot-theorem* works with only three types,
222+
`Integer`, `Real` and `Bool`, all of which SMT-Lib can handle.
222223
*copilot-theorem* works with *pure* reals and integers. Thus, it is unsafe in the
223224
sense it ignores integer overflow problems and the loss of precision due to
224225
floating point arithmetic.
225226

226227
#### The Kind2 prover
227228

228-
The *Kind2 prover* first translates the copilot specification into a *modular
229+
The *Kind2 prover* first translates the Copilot specification into a *modular
229230
transition system*. Then, a chain of transformations is applied to this system
230231
(for instance, in order to remove dependency cycles among nodes). After this,
231232
the system is translated into the *Kind2 native format* and the `kind2`
@@ -234,7 +235,7 @@ this process.
234235

235236
##### Modular transition systems
236237

237-
Let's look at the definition of a *modular transition systems*, in the
238+
Let's look at the definition of a *modular transition system*, in the
238239
`TransSys.Spec` module:
239240

240241
```haskell
@@ -295,10 +296,10 @@ types of variables:
295296

296297
##### The translation process
297298

298-
First, a copilot specification is translated into a modular transition system.
299+
First, a Copilot specification is translated into a modular transition system.
299300
This process is defined in the `TransSys.Translate` module. Each stream is
300-
associated to a node. The most significant task of this translation process is
301-
to *flatten* the copilot specification so the value of all streams at time *n*
301+
associated with a node. The most significant task of this translation process is
302+
to *flatten* the Copilot specification so the value of all streams at time *n*
302303
only depends on the values of all the streams at time *n - 1*, which is not the
303304
case in the `Fib` example shown earlier. This is done by a simple program
304305
transformation which turns this:
@@ -337,13 +338,13 @@ consistent. However, it can't be directly translated into the *Kind2 native
337338
file format*. Indeed, it is natural to bind each node to a predicate but the
338339
Kind2 file format requires that each predicate only uses previously defined
339340
predicates. However, some nodes in our transition system could be mutually
340-
recursive. Therefore, the goal of the `removeCycles :: Spec -> Spec` function
341-
defined in `TransSys.Transform` is to remove such dependency cycles.
341+
recursive. Therefore, the goal of the `removeCycles :: Spec -> Spec` function,
342+
defined in `TransSys.Transform`, is to remove such dependency cycles.
342343

343-
This function relies on the `mergeNodes :: [NodeId] -> Spec -> Spec` function
344-
which signature is self-explicit. The latter solves name conflicts by using the
345-
`Misc.Renaming` monad. Some code complexity has been added so the variable
346-
names remains as clear as possible after merging two nodes.
344+
This function relies on the `mergeNodes :: [NodeId] -> Spec -> Spec` function,
345+
whose signature is self-explicit. The latter solves name conflicts by using the
346+
`Misc.Renaming` monad. Some code complexity has been added so variable names
347+
remain as clear as possible after merging two nodes.
347348

348349
The function `removeCycles` computes the strongly connected components of the
349350
dependency graph and merge each one into a single node. The complexity of this
@@ -354,7 +355,7 @@ merged in most practical cases.
354355
After the cycles have been removed, it is useful to apply another
355356
transformation which makes the translation from `TransSys.Spec` to `Kind2.AST`
356357
easier. This transformation is implemented in the `complete` function. In a
357-
nutshell, it transforms a system such that
358+
nutshell, it transforms a system such that:
358359

359360
* If a node depends on another, it imports *all* its variables.
360361
* The dependency graph is transitive, that is if *A* depends of *B* which
@@ -374,25 +375,25 @@ inline spec = mergeNodes [nodeId n | n <- specNodes spec] spec
374375

375376
which discards all the structure of a *modular transition system* and turns it
376377
into a *non-modular transition system* with only one node. In fact, when
377-
translating a copilot specification to a kind2 file, two styles are available:
378+
translating a Copilot specification to a Kind2 file, two styles are available:
378379
the `Kind2.toKind2` function takes a `Style` argument which can take the value
379380
`Inlined` or `Modular`. The only difference is that in the first case, a call
380381
to `removeCycles` is replaced by a call to `inline`.
381382

382383
### Limitations of copilot-theorem
383384

384385
Now, we will discuss some limitations of the *copilot-theorem* tool. These
385-
limitations are organized in two categories: the limitations related to the
386-
Copilot language itself and its implementation, and the limitations related to
387-
the model-checking techniques we are using.
386+
limitations are split into two categories: limitations related to the Copilot
387+
language itself and its implementation, and limitations related to the
388+
model-checking techniques we are using.
388389

389390
#### Limitations related to Copilot implementation
390391

391-
The reification process used to build the `Core.Spec` object looses many
392-
informations about the structure of the original Copilot program. In fact, a
393-
stream is kept in the reified program only if it is recursively defined.
394-
Otherwise, all its occurences will be inlined. Moreover, let's look at the
395-
`intCounter` function defined in the example `Grey.hs`:
392+
The reification process used to build the `Core.Spec` object loses information
393+
about the structure of the original Copilot program. In fact, a stream is kept
394+
in the reified program only if it is recursively defined. Otherwise, all its
395+
occurrences will be inlined. Moreover, let's look at the `intCounter` function
396+
defined in the example `Grey.hs`:
396397

397398
```haskell
398399
intCounter :: Stream Bool -> Stream Word64
@@ -413,8 +414,8 @@ There are many problems with this:
413414
* It makes the inputs given to the SMT solvers larger and repetitive.
414415

415416
We can't rewrite the Copilot reification process in order to avoid these
416-
inconvenients as these informations are lost by GHC itself before it occurs.
417-
The only solution we can see would be to use *Template Haskell* to generate
417+
inconveniences as this information is lost by GHC itself before it occurs. The
418+
only solution we can see would be to use *Template Haskell* to generate
418419
automatically some structural annotations, which might not be worth the dirt
419420
introduced.
420421

@@ -423,7 +424,7 @@ introduced.
423424
##### Limitations of the IC3 algorithm
424425

425426
The IC3 algorithm was shown to be a very powerful tool for hardware
426-
certification. However, the problems encountered when verifying softwares are
427+
certification. However, the problems encountered when verifying software are
427428
much more complex. For now, very few non-inductive properties can be proved by
428429
*Kind2* when basic integer arithmetic is involved.
429430

@@ -433,32 +434,32 @@ the inductiveness* (CTI) for a property, these techniques are used to find a
433434
lemma discarding it which is general enough so that all CTIs can be discarded
434435
in a finite number of steps.
435436

436-
The lemmas found by the current version fo *Kind2* are often too weak. Some
437+
The lemmas found by the current version of *Kind2* are often too weak. Some
437438
suggestions to enhance this are presented in [1]. We hope some progress will be
438-
made in this area in a near future.
439+
made in this area in the near future.
439440

440-
A workaround to this problem would be to write kind of an interactive mode
441-
where the user is invited to provide some additional lemmas when automatic
442-
techniques fail. Another solution would be to make the properties being checked
441+
A workaround to this problem would be to write an interactive mode where the
442+
user is invited to provide some additional lemmas when automatic techniques
443+
fail. Another solution would be to make the properties being checked
443444
quasi-inductive by hand. In this case, *copilot-theorem* is still a useful tool
444445
(especially for finding bugs) but the verification of a program can be long and
445-
requires a high level of technicity.
446+
requires a high level of technical knowledge.
446447

447448
##### Limitations related to the SMT solvers
448449

449-
The use of SMT solvers introduces two kind of limitations:
450+
The use of SMT solvers introduces two kinds of limitations:
450451

451452
1. We are limited by the computing power needed by the SMT solvers
452453
2. SMT solvers can't handle quantifiers efficiently
453454

454455
Let's consider the first point. SMT solving is costly and its performances are
455456
sometimes unpredictable. For instance, when running the `SerialBoyerMoore`
456-
example with the *k-induction prover*, Yices2 does not terminate. However, the *z3*
457+
example with the *k-induction prover*, Yices2 does not terminate. However, the *Z3*
457458
SMT solver used by *Kind2* solves the problem instantaneously. Note that this
458459
performance gap is not due to the use of the IC3 algorithm because the property
459460
to check is inductive. It could be related to the fact the SMT problem produced
460461
by the *k-induction prover* uses uninterpreted functions for encoding streams instead
461-
of simple integer variables, which is the case when the copilot program is
462+
of simple integer variables, which is the case when the Copilot program is
462463
translated into a transition system. However, this wouldn't explain why the
463464
*k-induction prover* still terminates instantaneously on the `BoyerMoore` example,
464465
which seems not simpler by far.
@@ -472,10 +473,10 @@ property. This fact could be used to enhance the proof scheme system (see the
472473
*Future work* section). However, this trick is not always possible. For
473474
instance, in the `SerialBoyerMoore` example, the property being checked should
474475
be quantified over all integer constants. Here, we can't just introduce an
475-
arbitrary constant stream because it is the quantified property which is
476+
arbitrary constant stream because it is the quantified property that is
476477
inductive and not the property specialized for a given constant stream. That's
477-
why we have no other solution than replacing universal quantification by
478-
*bounded* universal quantification by assuming all the elements of the input
478+
why we have no other solution than replacing universal quantification with
479+
*bounded* universal quantification, assuming all the elements of the input
479480
stream are in the finite list `allowed` and using the function `forAllCst`:
480481

481482
```haskell
@@ -487,13 +488,13 @@ forAllCst l f = conj $ map (f . constant) l
487488
```
488489

489490
However, this solution isn't completely satisfying because the size of the
490-
property generated is proportionnal to the cardinal of `allowed`.
491+
property generated is proportional to the length of `allowed`.
491492

492493
#### Some scalability issues
493494

494-
A standard way to prove large programs is to rely on its logical structure by
495-
writing a specification for each of its functions. This very natural approach
496-
is hard to follow in our case because of
495+
A standard way to prove large programs is to rely on their logical structure,
496+
by writing a specification for each of their functions. This very natural
497+
approach is hard to follow in our case due to:
497498

498499
* The difficulty to deal with universal quantification.
499500
* The lack of *true* functions in Copilot: the latter offers metaprogramming
@@ -503,7 +504,7 @@ is hard to follow in our case because of
503504

504505
Once again, *copilot-theorem* is still a very useful tool, especially for
505506
debugging purposes. However, we don't think it is adapted to write and check a
506-
complete specification for large scale programs.
507+
complete specification for large-scale programs.
507508

508509
## Future work
509510

@@ -512,19 +513,19 @@ complete specification for large scale programs.
512513
These features are not currently provided due to the lack of important features
513514
in the Kind2 SMT solver.
514515

515-
#### Counterexamples displaying
516+
#### Displaying counterexamples
516517

517518
Counterexamples are not displayed with the Kind2 prover because Kind2 doesn't
518519
support XML output of counterexamples. If the last feature is provided, it
519-
should be easy to implement counterexamples displaying in *copilot-theorem*. For
520-
this, we recommend to keep some informations about *observers* in
520+
should be easy to implement displaying of counterexamples in *copilot-theorem*.
521+
For this, we recommend keeping some information about *observers* in
521522
`TransSys.Spec` and to add one variable per observer in the Kind2 output file.
522523

523524
#### Bad handling of non-linear operators and external functions
524525

525526
Non-linear Copilot operators and external functions are poorly handled because
526-
of the lack of support of uninterpreted functions in the Kind2 native format. A
527-
good way to handle these would be to use uninterpreted functions. With this
527+
of the lack of support for uninterpreted functions in the Kind2 native format.
528+
A good way to handle these would be to use uninterpreted functions. With this
528529
solution, properties like
529530
```haskell
530531
2 * sin x + 1 <= 3
@@ -533,7 +534,7 @@ with `x` any stream can't be proven but at least the following can be proved
533534
```haskell
534535
let y = x in sin x == sin y
535536
```
536-
Currently, the *Kind2 prover* fail with the last example, as the results of
537+
Currently, the *Kind2 prover* fails with the last example, as the results of
537538
unknown functions are turned into fresh unconstrained variables.
538539

539540
### Simple extensions
@@ -542,7 +543,7 @@ The following extensions would be really simple to implement given the current
542543
architecture of Kind2.
543544

544545
+ If inductive proving of a property fails, giving the user a concrete CTI
545-
(*Counterexample To The Inductiveness*, see the [1]).
546+
(*Counterexample To The Inductiveness*, see [1]).
546547

547548
+ Use Template Haskell to declare automatically some observers with the same
548549
names used in the original program.
@@ -559,29 +560,29 @@ architecture of Kind2.
559560

560561
- Declare assumptions and invariants next to the associated code instead of
561562
gathering all properties in a single place.
562-
- Declare a frequent code pattern which should be factorized in the
563-
transition problem (see the section about Copilot limitations)
563+
- Declare a frequent code pattern that can be factorized in the transition
564+
problem (see the section about Copilot limitations)
564565

565566
## FAQ
566567

567-
### Why does the code related to transition systems look so complex ?
568+
### Why does the code related to transition systems look so complex?
568569

569-
It is true the code of `TransSys` is quite complex. In fact, it would be really
570-
straightforward to produce a flattened transition system and then a Kind2 file
571-
with just a single *top* predicate. In fact, It would be as easy as producing
572-
an *IL* specification.
570+
It is true that the code of `TransSys` is quite complex. In fact, it would be
571+
really straightforward to produce a flattened transition system and then a
572+
Kind2 file with just a single *top* predicate. In fact, It would be as easy as
573+
producing an *IL* specification.
573574

574575
To be honest, I'm not sure producing a modular *Kind2* output is worth the
575576
complexity added. It's especially true at the time I write this in the sense
576577
that:
577578

578579
* Each predicate introduced is used only one time (which is true because
579-
copilot doesn't handle functions or parametrized streams like Lustre does and
580-
everything is inlined during the reification process).
580+
Copilot doesn't handle functions or parameterized streams like Lustre does
581+
and everything is inlined during the reification process).
581582
* A similar form of structure could be obtained from a flattened Kind2 native
582583
input file with some basic static analysis by producing a dependency graph
583584
between variables.
584-
* For now, the *Kind2* model-checker ignores these structure informations.
585+
* For now, the *Kind2* model-checker ignores these structures.
585586

586587
However, the current code offers some nice transformation tools (node merging,
587588
`Renaming` monad...) which could be useful if you intend to write a tool for

0 commit comments

Comments
 (0)