10. Don’t need amazing new language construct or fancy analysis
Solving complexity by adding more complexity is not working
We have all the parts we need –
consider our preconceptions & design with reasoning as a
primary concern at each step!
11. Eliminate foundational sources of
complexity!
• No Loops
• Immutable & referentially
transparent values
• Let and ITE based logic
• Fully determinized semantics
Make implicit information explicit!
• Explicit asserts, data invariants
• Strongly (and explicitly) typed –
including typed primitives
12.
13. function abs(x: Int): Int {
var sign = 1i;
if(x < 0i) {
sign = -1i;
}
return x * sign;
}
function allPos(...args: List<Int>): Bool {
return args.allOf(pred(x) => x >= 0i);
}
allPos(1i, 2i, 3i); //true
14. function abs(x: Int): Int
{
var sign = 1;
if(x < 0) {
sign = -1;
}
return x * sign;
}
function abs(x: Int): Int {
sign_0 = 1;
if(x < 0) {
sign_1 = -1;
}
sign_2 = φ(sign_0, sign_1);
return x * sign_2;
}
15. ref method intern(str: String): Int {
if(this.has(str)) { return this.get(str); } //use the ref this parameter
ref this.add(str, this.size()); //update the ref this parameter
return this.size(); //multi-return updated parameter
}
...
var env = Environment{};
let nameid1 = ref env.internString("hello");
let nameid2 = ref env.internString("goodbye");
_debug(env); //Environment{ "hello”=>0n, "goodbye”=>1n }
16. typedecl ZipcodeUS = /[0-9]{5}(-[0-9]{4})?/;
typedecl ZipcodeUS = /[0-9]{5}(-[0-9]{4})?/;
function isNYCode(s: StringOf<ZipcodeUS>): Bool {
return s.value().startsWith(/1[0-4]/);
}
isNYCode("10001"ZipcodeUS) //true
isNYCode("40506"ZipcodeUS) //false
typedecl ZipcodeUS = /[0-9]{5}(-[0-9]{4})?/;
function isNYCode(s: StringOf<ZipcodeUS>): Bool {
return s.value().startsWith(/1[0-4]/);
}
isNYCode("10001"ZipcodeUS) //true
isNYCode(“40506"ZipcodeUS) //false
isNYCode("12") //type error not a StringOf<ZipcodeUS>
isNYCode("WC1E"PostcodeUK) //type error not a StringOf<ZipcodeUS>
17. function gcd(x: Int, y: Int): Int
requires x > 0i && y > 0i; //check is always done
ensures test $return > 0i; //only in debug/test build
{
...
}
entity CalendarEvent {
field name: String;
field location: String;
field start: DateTime;
field duration: Minutes;
invariant $name !== "";
invariant $location !== "";
invariant $duration > 0n_Minutes;
...
}
18.
19. (define-fun abs((x Int)) Int
(let ((sign 1))
(ite (x < 0)
(let ((@sign_1 -1))
(* x @sign_1)
)
(* x sign)
)
)
)
function abs(x: Int): Int
{
var sign = 1i;
if(x < 0i) {
sign = -1i;
}
return x * sign;
}
20.
21. /*Find the largest pair of values from the lists.*/
function findMaxPair(x: List<Int>, y: List<Int>): [Int, Int]
{
defer;
}
//=> return [x.max(), y.max()];
ensures x.contains($return.0) && y.contains($return.1);
examples [
[List{3, 2}, List{3, 5} => [2, 5]]
];
//=> return List::zip(x, y).maxArg(fn(v) => v.0);
//=> return List::zip(x, y).maxArg(fn(v) => v.0 + v.1);
Fails on Input: [List{3, 2}, List{3, 5}]
Result - [3, 5]
Expected + [2, 5]
Can you debug this and fix the code?
26. typedecl Fahrenheit = Int;
typedecl Mph = Nat;
typedecl Percentage = Nat & {
invariant $value <= 100n;
}
let a = 100n_Percentage;
let b = 101n_Percentage; //Static Error
let p = a – 25n_Percentage;
let q = a + 25n_Percentage; //Runtime Error
let a = 100i_Fahrenheit;
let b = 99i_Fahrenheit;
check a < b;
27. (define-fun abs((x Int)) Int
(let ((sign 1))
(ite (x < 0)
(let ((@sign_1 -1))
(* x @sign_1)
)
(* x sign)
)
)
)
function abs(x: Int): Int {
var sign = 1i;
if(x < 0i) {
sign = -1i;
}
return x * sign;
}