-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Implement DexVerify and LTD #34
Open
OCHyams
wants to merge
26
commits into
SNSystems:main
Choose a base branch
from
OCHyams:LTD_feature
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
1a0fcaf
Initial commit
OCHyams b6be107
Implement LTL
OCHyams cbcc1c5
Rewrite LTL_work.md as a tutorial/reference
OCHyams 2fd3260
Improve DexVerify arg parsing
OCHyams f7fd867
Add bare-bones examples
OCHyams 1474498
Implement naive DexVerify penalty
OCHyams b0cb8fb
Rename composite operator member 'operand'
OCHyams 6e3f33f
NFC cleanup changes
OCHyams 55a71a0
Add Release() to command list and continue tidy up
OCHyams 5e6b6c4
Add LTD functions to quick reference
OCHyams 49309de
Make new DexExpectProgramState command LTD compatible
OCHyams 80cdbed
Composite operators use default operator string representation
OCHyams 0a6ec7b
Implement LTD Next() operator
OCHyams 1633af3
Update LTL_work with Next operator info
OCHyams fda1a7d
Unify composite operators with an interface
OCHyams 63216b9
Add LTD After() operator
OCHyams ffe88ae
Allow Dexter commands to specify subcommands
OCHyams 4a17d0f
Add LTD commands as DexVerify subcommands
OCHyams 911eaca
Tidy up
OCHyams 2f8dc00
Fix some LTL_work mistakes
OCHyams 87e2410
Remove cruft from OperatorTypes.py
OCHyams e59362b
Implement LTD operator type BinaryOperatorTree
OCHyams 27e023c
Add LTD operator Ordered
OCHyams afbd9ff
Fix LTD Next() and simplify Henceforth()
OCHyams 7ee89fa
Improve LTD docstrings
OCHyams 32af41a
Clean up BinaryOperatorTree
OCHyams File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
# DexVerify | ||
## Contents | ||
1. Introduction | ||
2. Motivation | ||
3. Theory | ||
4. Quick reference | ||
|
||
## 1. Introduction | ||
A DexVerify command takes the form `DexVerify(p: Proposition)`. It will verify | ||
that the proposition `p` is true. The most basic proposition, an atomic | ||
proposition, expresses the expected state of the program at a given point in | ||
time, or `True` or `False`. | ||
|
||
For example, if you wanted to verify that at a given point in time the variable | ||
`a` is equal to `5`, you may write (1): | ||
``` | ||
DexVerify(Expect('a', '5')) | ||
``` | ||
|
||
In this example, it just so happens that the "given point in time" is the first | ||
step that the debugger takes (2). This is not a very useful verification | ||
because we could be stepping through pre-main startup code. | ||
|
||
If you want to check that eventually a local variable `a` is `5` you'd write: | ||
``` | ||
DexVerify(Eventually(Expect('a', '5'))) | ||
``` | ||
|
||
`Eventually` is a temporal operator. **Temporal** operators work over **time**. | ||
Intuitively, `Eventually(p)` means that `p` must become true at some point | ||
during program execution. | ||
|
||
`Eventually(p)` is defined as `Until(True, p)`. It's easy to explain how this | ||
works if we take a look at `Until(p, q)`. `Until`, `Weak` and `Next` | ||
(see the Quick Reference section) are used to define all other temporal | ||
operators. All operators are exposed as functions so the formulae read in | ||
Polish, or 'prefix', notation. | ||
|
||
`Until(p, q)` means that `q` must hold in the future, and **until** then `p` | ||
must hold. | ||
|
||
Looking at `Eventually(p)` again then; `Until(True, p)` can be translated to | ||
"`p` must hold in the future, and until then, `True` must hold". `True` *is* | ||
always `True` so you could instead just say "`p` must hold in the future". | ||
|
||
Temporal operators are very useful but are not a catch-all solution. What if | ||
you want to say eventually `a == 5` and eventually `b == 1`? It's pretty much | ||
as easy as writing that. This is where boolean connectives come in: | ||
``` | ||
DexVerify(And(Eventually(Expect('a', '5')), Eventually(Expect('b', '1')))) | ||
``` | ||
|
||
This formula doesn't impose any ordering on the `Expect` propositions. | ||
If you want to say that `b == 1` at some point in the future **after** | ||
`a == 5` you'd write: | ||
``` | ||
DexVerify(After(Expect('b', '1'), Expect('a', '5'))) | ||
``` | ||
|
||
For more examples have a look in dexter/examples/LTD. Please be aware that the | ||
prefix "xfail_" indicates that running that test should result in a failure. | ||
|
||
## 2. Motivation | ||
|
||
[TODO] Write this section | ||
|
||
|
||
## 3. Theory | ||
The DexVerify command formulae are based on Linear Temporal Logic (LTL). | ||
The standard definition of LTL is as follows (modified from | ||
[this](https://www.win.tue.nl/~jschmalt/teaching/2IX20/reader_software_specification_ch_9.pdf) | ||
source): | ||
|
||
``` | ||
p ::= a | p /\ p | !p | Xp | p U p | ||
``` | ||
|
||
Where: | ||
* `a` is an atomic proposition | ||
* `p` represents a valid LTL formula | ||
* `X` denotes the ”next” operator | ||
* `U` denotes the ”until” operator | ||
* `!` denotes negation | ||
* `/\` denotes logical "and" | ||
|
||
|
||
Usual boolean connectives can be derived: | ||
``` | ||
!(p /\ q) == p \/ q // (disjunciton) | ||
!p \/ q == p --> q // (implication) | ||
``` | ||
|
||
From the syntax, we define the following: | ||
``` | ||
p \/ !p == True | ||
!True == False | ||
``` | ||
|
||
Further temporal operators can be derived: | ||
``` | ||
F p == true U p // p will hold at some point in the Future. | ||
``` | ||
There are others, e.g. Weak(W) and Release(R) and more. | ||
|
||
[This](http://www.lsv.fr/~gastin/ltl2ba/index.php) website is a fantastic | ||
resource for viewing your LTL formula as a Büchi automaton. | ||
|
||
Operator precedence doesn't matter for our case because all operators | ||
are exposed as functions, but for infix LTL: | ||
1. Unary operators | ||
2. Binary temporal | ||
3. Binary boolean | ||
|
||
|
||
## 4. Quick reference | ||
### Atomic propositions | ||
#### Boolean | ||
``` | ||
True | ||
False | ||
``` | ||
Not strictly "atomic propositions" in terms of LTL theory. | ||
|
||
#### Expect | ||
``` | ||
Expect(p, q) | ||
``` | ||
Debugger C++ expression `p` must evaluate to value `q`. | ||
|
||
### Boolean functions | ||
|
||
#### And | ||
|
||
#### Or | ||
|
||
#### Not | ||
|
||
### Temporal functions | ||
|
||
#### Until | ||
``` | ||
Until(p, q) | ||
``` | ||
`q` must eventually hold and until then `p` must hold.<br/> | ||
LTL definition: `U` ≡ Until ≡ `q` holds at some time `i >= 0` and | ||
`p` holds for all `0 <= k < i`. | ||
|
||
#### Weak | ||
``` | ||
Weak(p, q) | ||
``` | ||
`p` must hold so long as `q` does not.<br/> | ||
LTL definition: `W` ≡ Weak ≡ Weak until ≡ `q` holds at some | ||
time `i >= 0` or never holds `i = inf` and `p` holds for all `0 <= k < i`. | ||
|
||
#### Next | ||
``` | ||
Next(p) | ||
``` | ||
`p` must hold at the next time step.<br/> | ||
LTL definition: `X` ≡ Next ≡ `p` holds at next step. | ||
|
||
#### Eventually | ||
``` | ||
Eventually(p) | ||
``` | ||
`p` must eventually hold.<br/> | ||
LTL definition: `F` ≡ Finally ≡ Eventually ≡ Future ≡ | ||
`True U p` | ||
|
||
#### Release | ||
``` | ||
Release(p, q) | ||
``` | ||
`p` must eventually hold and up to and including that time `q` must hold. | ||
NOTE: Operand order and keyword *including*.<br/> | ||
LTL definition: `R` ≡ Release ≡ `q W (q /\ p)` | ||
|
||
#### Henceforth | ||
``` | ||
Henceforth(p) | ||
``` | ||
`p` must hold from now onwards.<br/> | ||
LTL definition: `G` ≡ Globally ≡ `False R p` | ||
|
||
#### After | ||
``` | ||
After(p, q) | ||
``` | ||
`p` holds at some point after `q`. Both must hold at some point but not | ||
simultaneously.<br/> | ||
LTL definition: `A` ≡ After ≡ `q /\ X(F(p))` | ||
|
||
#### Ordered | ||
``` | ||
Ordered(p, q, r...) | ||
``` | ||
The propositions may hold at any time so long as each proposition holds before | ||
the next (left to right) and they do all hold at some point. | ||
LTL definition: `O` ≡ Ordered ≡ `r... A (q A p)` | ||
|
||
--- | ||
### Examples | ||
[TODO] Add examples after coming up with some syntactic sugar for the common | ||
patterns. | ||
|
||
|
||
### [TODO] / notes | ||
1. The Expect syntax will not look anything like this. | ||
2. Makes sense for the first step to be stepping into main -- discuss with team. | ||
3. It seems like all DexVerify() commands start wth Eventually. It might make | ||
sense to bake this in? E.g. | ||
DexVerify(p) == Eventually(And(Expect({frames: {main}}), p)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# DExTer : Debugging Experience Tester | ||
# ~~~~~~ ~ ~~ ~ ~~ | ||
# | ||
# Copyright (c) 2018 by SN Systems Ltd., Sony Interactive Entertainment Inc. | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy | ||
# of this software and associated documentation files (the "Software"), to deal | ||
# in the Software without restriction, including without limitation the rights | ||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
# copies of the Software, and to permit persons to whom the Software is | ||
# furnished to do so, subject to the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be included in | ||
# all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
# THE SOFTWARE. | ||
"""[TODO] Add words | ||
""" | ||
import pprint | ||
OCHyams marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
from dex.command.CommandBase import CommandBase | ||
from dex.command.commands.LTD.internal.Proposition import Boolean | ||
from dex.dextIR import DextIR, DextStepIter | ||
from dex.command.commands.LTD import ( | ||
Or, And, Not, Next, Weak, After, Until, Expect, Release, Eventually, | ||
Henceforth, ExpectState, Ordered | ||
) | ||
|
||
|
||
class DexVerify(CommandBase): | ||
def __init__(self, *args): | ||
if len(args) != 1: | ||
raise TypeError('Expected exactly one arg') | ||
|
||
self.model = args[0] | ||
if isinstance(self.model, bool): | ||
self.model = Boolean(self.model) | ||
|
||
def eval(self, program: DextIR) -> bool: | ||
# [TODO] return (bool, list) where list is a set of nested lists of | ||
# string which describte the verification trace | ||
trace_iter = DextStepIter(program) | ||
return self.model.eval(trace_iter) | ||
|
||
def get_subcommands(): | ||
return { | ||
'Or': Or, | ||
'And': And, | ||
'Not': Not, | ||
'Next': Next, | ||
'Weak': Weak, | ||
'After': After, | ||
'Until': Until, | ||
'Expect': Expect, | ||
'Ordered': Ordered, | ||
'Release': Release, | ||
'Eventually': Eventually, | ||
'Henceforth': Henceforth, | ||
'ExpectState': ExpectState, | ||
} | ||
|
||
def __str__(self): | ||
return "DexVerify({})".format(self.model) | ||
|
||
def __repr__(self): | ||
return self.__str__() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Basic operators | ||
from dex.command.commands.LTD.public.BasicOperators import ( | ||
Not, And, Or, | ||
) | ||
|
||
## Temporal operators | ||
from dex.command.commands.LTD.public.BasicOperators import ( | ||
Until, Weak, Next, | ||
) | ||
|
||
## Atomic propositions | ||
from dex.command.commands.LTD.public.Expect import Expect | ||
from dex.command.commands.LTD.public.ExpectState import ExpectState | ||
|
||
# Composit operators | ||
OCHyams marked this conversation as resolved.
Show resolved
Hide resolved
|
||
## Temporal operatos | ||
from dex.command.commands.LTD.public.CompositeOperators import ( | ||
Eventually, Henceforth, Release, After, Ordered | ||
) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Words should be added before merging