# Algebra and subst Rules

In this section, we will learn our first two proof rules for programming logic – `algebra`

and `subst`

.

## Verifying simple programs

Before we delve into our new proof rules, let’s look at the process for verifying simple Logika programs (ones that include user input, variable initialization, and assignment statements using different operations). Here, the `// -->`

lines are pieces of the verification process that you must add (or consider) in order to prove correctness of your program, and the other lines are the code of the program.

```
get user input / set initial variable values
// --> add assume statements to specify what must be true about the input
program statement
// --> add logic block to evaluate what has happened in the program
program statement
// --> add logic block to evaluate what has happened in the program
program statement
// --> add logic block to evaluate what has happened in the program
(...more program statements)
// --> add assert statements to express what our program did
```

We see that if our program involves user input, then we must consider whether our program will only work correctly for certain input values. In that situation, we express our assumptions using `assume`

statements.

After each program statement, we must add a logic block to evaluate what changed on that line of code. We will see more details on these logic blocks throughout the rest of this chapter. Recall that the syntax for those logic blocks looks like:

```
l"""{
lineNumber. claim justification
// ... (more claims/justifications)
}"""
```

Finally, we add one or more `assert`

statements to express what our program did. These are usually placed at the end of a program, but sometimes we have assert statements throughout the program to describe the progress up to that point.

## Algebra justification

The `algebra`

justification can be used for ANY algebraic manipulation on previous claims. When using this justification, include all relevant proof line numbers in whatever order (you might use as few as zero line numbers or as many as 3+ line numbers).

### Example

Consider this example:

```
import org.sireum.logika._
var x: Z = 6
var y: Z = x
//this assert will not hold yet
assert (y == 6)
```

Following our process from above, we add logic blocks after each program statement. In these logic blocks, we start by listing the previous program statement as a premise:

```
import org.sireum.logika._
var x: Z = 6
l"""{
1. x == 6 premise
}"""
var y: Z = x
l"""{
1. y == x premise
//need claim "y == 6" for our assert to hold
}"""
//this assert will not hold yet
assert (y == 6)
```

For our assert to hold, we must have EXACTLY that claim in a previous logic block – so we know we want our second logic block to include the claim `y == 6`

.

Here is the program with the second logic block completed – the assert statement will now hold.

```
import org.sireum.logika._
var x: Z = 6
l"""{
1. x == 6 premise
}"""
var y: Z = x
l"""{
1. y == x premise
2. x == 6 premise //established in a previous logic block, and x is unchanged since then
3. y == 6 algebra 1 2 //we know y is 6 using the claims from lines 1 and 2
}"""
//this assert will hold
assert (y == 6)
```

We could have also deleted the first logic block in this example. We would still be able to claim `x == 6`

as a premise in the last logic block, as `x`

had not changed since being given that value.

## subst

We have two deduction rules that involve substitution – `subst1`

and `subst2`

. Both of these rules are similar to the find/replace feature in text editors. They preserve truth by replacing one proposition with an equivalent one.

The `algebra`

justification will work for most mathematical manipulation. However, it will not work for any claim involving `∧`

, `∨`

, `→`

, `⊥`

, `∀`

, `∃`

– in those cases, we will be required to use substitution instead.

### subst1 justification

Here is the syntax for the `subst1`

rule. In the example below, line `m`

must be an equivalence (something equals something else). Line `n`

can be anything.

```
l"""{
...
m. LHS_M == RHS_M (some justification)
...
n. LINE_N (some justification)
...
p. (claim) subst1 m n
}"""
```

`(claim1)`

rewrites `LINE_N`

by substituting all ocurrences of `LHS_M`

(the FIRST side of line `m`

) with `RHS_M`

. Here is an example:

```
l"""{
1. x + 1 == y - 4 (some justification)
2. x*(x + 1) == (x + 1) + y (some justification)
3. x*(y - 4) == (y - 4) + y subst1 1 2
}"""
```

We wrote line 2 by replacing each occurence of `x + 1`

with `y - 4`

.

### subst2 justification

Here is the syntax for the `subst2`

rule. Just as with `subst1`

, line `m`

must be an equivalence (something equals something else). Line `n`

can be anything.

```
l"""{
...
m. LHS_M == RHS_M (some justification)
...
n. LINE_N (some justification)
...
p. (claim) subst2 m n
}"""
```

`(claim1)`

rewrites `LINE_N`

by substituting all ocurrences of `RHS_M`

(the SECOND side of line `m`

) with `LHS_M`

. Here is an example:

```
l"""{
1. x + 1 == y (some justification)
2. y*(x + 1) == (x + 1) + y (some justification)
3. (x + 1)*(x + 1) == (x + 1) + (x + 1) subst2 1 2
}"""
```

We wrote line 2 by replacing each occurence of `y`

with `x + 1`

. Note that we put parentheses around our first replacement to ensure a product equivalent to the original statement.