Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
84e46f8
add assert statement, add verification for assignment and assert stat…
AmoghBhagwat Feb 3, 2025
b19acd8
add conversion to SSA, fix implementation
AmoghBhagwat Feb 7, 2025
efcfba0
revert to assignment BMC
AmoghBhagwat Feb 10, 2025
8a478d4
update .gitignore
AmoghBhagwat Feb 10, 2025
e8110c7
converted ir into 3ac
AmoghBhagwat Feb 10, 2025
978b285
modify cfg builder to include TAC instructions
AmoghBhagwat Feb 11, 2025
c18cd00
modify cfg,bmc for TAC format
AmoghBhagwat Feb 13, 2025
812d116
added ssa to chiron
debrajk22 Feb 16, 2025
57ebb32
added cfg of ssa
debrajk22 Feb 16, 2025
b8354aa
added bmc for parts of SSA ir
debrajk22 Feb 20, 2025
7481e9b
Update dependencies
debrajk22 Feb 20, 2025
798df64
fixed initialization bug
debrajk22 Mar 3, 2025
64a1a83
ssa cfg update
AmoghBhagwat Mar 4, 2025
92c6dca
Merge branch 'master' of https://github.com/debrajk22/Chiron-Framework
AmoghBhagwat Mar 4, 2025
185cda6
rename variables, fix directory structure
AmoghBhagwat Mar 4, 2025
5c01c86
fix free variable ssa conversion bug
AmoghBhagwat Mar 4, 2025
d89f28d
add condition for each basic block execution
AmoghBhagwat Mar 10, 2025
e77bce5
fix block condition logic
AmoghBhagwat Mar 11, 2025
f326a93
TODO: add basic block conversion
AmoghBhagwat Mar 11, 2025
f36115b
set conditions for basic blocks
debrajk22 Mar 12, 2025
85f8f38
converted phi to smt
debrajk22 Mar 12, 2025
05b7bea
revert block condition, print only input variables for bug
AmoghBhagwat Mar 12, 2025
9e1fc9b
added support for move, pen, and goto command
debrajk22 Mar 12, 2025
2d7cc37
fix ssa, rename left
AmoghBhagwat Mar 13, 2025
388d9ff
fix conflict
AmoghBhagwat Mar 13, 2025
f9511e7
fix ssa
AmoghBhagwat Mar 14, 2025
9bc76ab
added modulo operator and handled angle of turtle
debrajk22 Mar 17, 2025
218e700
fixed bugs
debrajk22 Mar 17, 2025
d3ec4f2
fix SSA
AmoghBhagwat Mar 18, 2025
9470aca
modify BMC to check unknown verdict
AmoghBhagwat Mar 18, 2025
80fc3be
add loop unrolling
AmoghBhagwat Mar 18, 2025
ba29237
included termainal functionalities
debrajk22 Mar 19, 2025
c00d9f6
fixed assert bug
debrajk22 Mar 19, 2025
3965c57
added sin and cos
debrajk22 Mar 19, 2025
a64c9e7
fixed multiple solutions from z3
debrajk22 Mar 20, 2025
2b8b37f
fixed type conversion
debrajk22 Mar 20, 2025
faf8ca7
debugged cases when loop does not run or if cond is not true
debrajk22 Mar 20, 2025
c704482
removed testing hardcode
debrajk22 Mar 20, 2025
3e04596
handled typecasting for sin, cos and assert
debrajk22 Mar 20, 2025
7091d0a
fix variable repeat unrolling
AmoghBhagwat Mar 20, 2025
b818ca2
restricted 90 deg rotations only
debrajk22 Mar 24, 2025
8aa177e
fix left right turn, assert statement during runtime
AmoghBhagwat Mar 29, 2025
4a1cd00
add assume command
AmoghBhagwat Mar 29, 2025
9686dff
added implies in assert, assume and assume before loops
debrajk22 Apr 5, 2025
b124abd
modified free variables
debrajk22 Apr 5, 2025
6a51979
add decorator for unroll bound for each loop
AmoghBhagwat Apr 5, 2025
bacb2a1
modulo int, add decimal support in language, angle config file
AmoghBhagwat Apr 7, 2025
4e2d8a2
linear time algorithm for dominator tree
AmoghBhagwat Apr 7, 2025
7b4dbb2
cleanup
AmoghBhagwat Apr 10, 2025
7f5057a
added description of bmc
debrajk22 Apr 16, 2025
9fb040d
added BMC.md
debrajk22 Apr 16, 2025
260ba74
added multiline comments
debrajk22 Apr 16, 2025
f9025dd
created test cases with explaination
debrajk22 Apr 17, 2025
d8fe94d
added nested loops
debrajk22 Apr 17, 2025
3696ce3
add path planning example
AmoghBhagwat Apr 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,6 @@ cython_debug/

# Extra files and hidden folder.
testcases/
build/
build/

*.png
100 changes: 100 additions & 0 deletions BMC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Bounded Model Checker (BMC) of Chiron

## Introduction

A Bounded Model Checker (BMC) engine is a verification tool used to check the satisfiability of a condition within a given bound without actually running the code. It systematically explores all possible states of a system up to a specified depth to detect errors.

The BMC engine works by encoding the system's behavior and the properties to be verified into a logical formula. This formula is then solved using a SAT (Satisfiability) solver. If the solver finds a solution within the bounds, it indicates a counterexample that demonstrates a violation of the property being checked. If no solution is found within the given bound, the system is considered correct up to the bounds.

### What makes BMC interesting

The BMC engine provides an automated approach to verify the correctness of complex systems. Unlike traditional testing, which relies on specific test cases, BMC explores all possible states within a given bound, ensuring thorough coverage. This makes it particularly effective in uncovering subtle bugs that might be missed by conventional methods.

The use of SAT solvers to encode and solve logical formulas demonstrates the power of combining formal methods with computational tools. The ability to detect counterexamples and provide concrete scenarios where a property fails is invaluable for debugging and improving system reliability.

Moreover, BMC's ability to handle constraints, conditions, and configurations, including loop unrolling and custom angle restrictions, makes it a versatile tool for diverse software verification applications.

## How to use Chiron BMC

### Adding Bounds
We can restrict the domain of variables by `assume` statements. For example:
- `assume :x >= 0` bounds the domain of variable `:x` in the positive side of number line
- `assume :x*:x + :y*:y <= r*r` restricts the point `(:x, :y)` inside the circle of radius `r`.

### Adding Conditions
We add the conditions to be checked by `assert` statements. For example:
- `assert :x >= 0 && :y >= 0` checks whether the point `(:x, :y)` lies in the first quadrant
- `assert :x*:x + :y*:y >= r*r` checks whether the point `(:x, :y)` lies outside the circle of radius `r`.

### Handling Loops

Loops in the code are managed through a technique called **loop unrolling**. Loop unrolling involves replicating the loop's body multiple times, constrained by a specified unroll bound. For the purpose of understaning unrolling, we store the unrolled code in file `unrolled_code.tl`.

### Adding Loop Unroll Bound
`-ub <UNROLL_BOUND>` is used to set the unroll bound of loops. By default, it is set to 10.

A custom unroll bound for a particular loop can be set by using the `@unroll` decorator. For example,
```c
@unroll <UNROLL_BOUND> repeat <value> [
...
]
```

### Tracking Position of Turtle
We assume that turle starts at position $(0, 0)$ and facing at $0^\circ$ angle with respect to the positive direction of $x$-axis. The position of turtle is maintained by the variables `:turtleX` ($x$-coordinate), `:turtleY` ($y$-coordinate) and `:turtleThetaDeg` (angle in degrees).

### Adding Angle Constraints
By default, the turtle can face towards $0^\circ$, $90^\circ$, $180^\circ$ and $270^\circ$. Custom angles can be added by maintaining a configuration file that specifies the angles along with their cosine and sine values in the following format:

```plaintext
<angle_1>, <cos(angle_1)>, <sin(angle_1)>
<angle_2>, <cos(angle_2)>, <sin(angle_2)>
...
```

This configuration file is then passed to the BMC engine using the `-aconf <filename>` argument.

### Tracking Pen State
The variable `:turtlePen` is used to maintain the up/down state of pen.
- `:turtlePen = 0` indicates pendown state
- `:turtlePen = 1` indicates penup state

At the start of the program, pen is in pendown state.

## Examples
Examples demonstrating working of the BMC engine with explaination are provided in the `/ChironCore/bmc_examples/` directory. To run the BMC engine on these test cases, navigate to the `ChironCore` directory and execute the following command:

```bash
./chiron.py <path_to_test_file> -bmc -ub <UNROLL_BOUND> -aconf <ANGLE_CONF_FILE>
```
where `-ub` and `-aconf` are optional arguments

## Implementation Methodology
We have added support for `assume` statement, `assert` statement, `modulo` operator, `float` numbers, `single line comments` and `multi-line comments` to Chiron. We have also added code to convert Chiron Intermediate Representation (IR) into Three Address Code (TAC) and Static Single Assignment (SSA).

The working of BMC engine is explained as follows:

1. **Loop Unrolling**:
All the loops of the code are unrolled based on the unroll bound and the unrolled code is used for further processing.

2. **Converting Chiron IR into TAC**:
The Chiron IR of the unrolled code is generated and is transformed into TAC to simplify the representation of operations and facilitate further analysis. We show the TAC in `tac_cfg.png`.

3. **Generating SSA**:
The TAC is converted into SSA form to simplify data flow analysis and accurately track variable dependencies and states throughout the program. We show the SSA in `ssa_cfg.png`.

4. **SAT Solver Integration**:
The SSA form is translated into SMT-LIB statements. This process encodes the constraints, conditions, and properties into a series of logical assertions and declarations to accurately represent the program's semantics. These statements are then checked for satisfiability using the Z3 solver.

5. **Reporting Results**:
- **Checking tightness of bounds**:
The BMC engine verifies if a solution exists within the given bounds. If no solution is found, it suggests relaxing the bounds.

- **Checking satisfiability under all bounds**:
The BMC engine checks satisfiability until either a counterexample is found or all possible states of the program within the specified bounds are exhausted. If no violations are detected, the system is considered correct up to the given bounds.

- **Counter Example generation**:
If the BMC engine detects a violation, it generates a counterexample for the input variables.

## Acknowledgement
We express our gratitude to Professor Subhajit Roy and Chiron team for their unwavering guidance and support throughout the duration of this project. Their assistance significantly influenced the course of our journey, making it markedly distinct from what it would have been otherwise.
14 changes: 12 additions & 2 deletions ChironCore/ChironAST/ChironAST.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,20 @@ def __init__(self, condition):
def __str__(self):
return self.cond.__str__()

# Not Implemented Yet.
class AssertCommand(Instruction):
def __init__(self, condition):
self.cond = condition

def __str__(self):
return self.cond.__str__()

class AssumeCommand(Instruction):
def __init__(self, condition):
self.cond = condition

def __str__(self):
return self.cond.__str__()

class MoveCommand(Instruction):
def __init__(self, motion, expr):
self.direction = motion
Expand Down Expand Up @@ -126,6 +132,10 @@ class Div(BinArithOp):
def __init__(self, lexpr, rexpr):
super().__init__(lexpr, rexpr, "/")

class Mod(BinArithOp):
def __init__(self, lexpr, rexpr):
super().__init__(lexpr, rexpr, "%")


# --Boolean Expressions-----------------------------------------------

Expand Down Expand Up @@ -221,7 +231,7 @@ class Value(Expression):

class Num(Value):
def __init__(self, v):
self.val = int(v)
self.val = float(v)

def __str__(self):
return str(self.val)
Expand Down
17 changes: 17 additions & 0 deletions ChironCore/ChironAST/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ def visitMulExpr(self, ctx:tlangParser.MulExprContext):
return ChironAST.Mult(left, right)
elif ctx.multiplicative().DIV():
return ChironAST.Div(left, right)


# Visit a parse tree produced by tlangParser#valueExpr.
def visitModExpr(self, ctx:tlangParser.ModExprContext):
left = self.visit(ctx.expression(0))
right = self.visit(ctx.expression(1))
if ctx.modulo().MOD():
return ChironAST.Mod(left, right)


# Visit a parse tree produced by tlangParser#parenExpr.
Expand Down Expand Up @@ -142,6 +150,8 @@ def visitCondition(self, ctx:tlangParser.ConditionContext):
def visitValue(self, ctx:tlangParser.ValueContext):
if ctx.NUM():
return ChironAST.Num(ctx.NUM().getText())
elif ctx.FLOAT():
return ChironAST.Num(ctx.FLOAT().getText())
elif ctx.VAR():
return ChironAST.Var(ctx.VAR().getText())

Expand Down Expand Up @@ -172,3 +182,10 @@ def visitMoveCommand(self, ctx:tlangParser.MoveCommandContext):

def visitPenCommand(self, ctx:tlangParser.PenCommandContext):
return [(ChironAST.PenCommand(ctx.getText()), 1)]

def visitAssertionCommand(self, ctx:tlangParser.AssertionCommandContext):
return [(ChironAST.AssertCommand(self.visit(ctx.condition())), 1)]

def visitAssumeCommand(self, ctx:tlangParser.AssumeCommandContext):
return [(ChironAST.AssumeCommand(self.visit(ctx.condition())), 1)]

Loading