Skip to content

Instantly share code, notes, and snippets.

@jlouis
Created October 29, 2009 17:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlouis/221612 to your computer and use it in GitHub Desktop.
Save jlouis/221612 to your computer and use it in GitHub Desktop.
%%% The absurd statement. A tool for reasoning from false.
%%% Jesper Louis Andersen 2008
void : type. %name void _|_.
%freeze void.
%%% Booleans
%%% Jesper Louis Andersen
% ===== The Boolean type =====
bool : type.
bool/true : bool.
bool/false : bool.
% Convenience
true = bool/true.
false = bool/false.%%% Peano Style Arithmetic
%%% Jesper Louis Andersen
% ===== Syntax =====
nat : type. %name nat N.
nat/z : nat.
nat/s : nat -> nat.
%% Notation
z = nat/z.
s = nat/s.
% ===== Lists of natural numbers =====
natlist : type. %name natlist NATL.
natlist/nil : natlist.
natlist/cons : nat -> natlist -> natlist.
%%% Sizes of natlists
natlist-size : natlist -> nat -> type.
%mode natlist-size +NL -N.
natlist-size/nil : natlist-size natlist/nil z.
natlist-size/cons : natlist-size (natlist/cons N NL) (s K)
<- natlist-size NL K.
% ===== Reflexive equality =====
nat-eq : nat -> nat -> type.
%mode nat-eq +N1 +N2.
nat-eq/z : nat-eq z z.
nat-eq/s : nat-eq (s N1) (s N2)
<- nat-eq N1 N2.
%worlds () (nat-eq _ _).
%terminates N1 (nat-eq N1 _).
% ===== Non-equality of natural numbers =====
nat-neq : nat -> nat -> type.
%mode nat-neq +N1 +N2.
nat-neq/zs : nat-neq z (s _).
nat-neq/sz : nat-neq (s _) z.
nat-neq/ss : nat-neq (s S1) (s S2)
<- nat-neq S1 S2.
%worlds () (nat-neq _ _).
%terminates T (nat-neq T _).
% ===== Total ordering =====
nat-lt : nat -> nat -> type.
%mode nat-lt +N1 +N2.
nat-lt/z : nat-lt z (s _).
nat-lt/s : nat-lt (s N1) (s N2)
<- nat-lt N1 N2.
%worlds () (nat-lt _ _).
%terminates N1 (nat-lt N1 _).
% ===== Operators =====
%% The ''plus'' operation.
plus-nat : nat -> nat -> nat -> type.
%mode plus-nat +N1 +N2 -N3.
plus-nat/z : plus-nat z N N.
plus-nat/s : plus-nat (s N1) N2 (s N3)
<- plus-nat N1 N2 N3.
%worlds () (plus-nat _ _ _).
%total T (plus-nat T _ _).
%query 1 * (plus-nat (s z) (s (s z)) (s (s (s z)))).
%query 1 * (plus-nat z (s z) (s z)).
%% The ''monus'' operation.
monus-nat : nat -> nat -> nat -> type.
%mode monus-nat +N1 +N2 -N3.
monus-nat/z/1 : monus-nat z N z.
monus-nat/z/2 : monus-nat N z N.
monus-nat/s : monus-nat (s N1) (s N2) N3
<- monus-nat N1 N2 N3.
%worlds () (monus-nat _ _ _).
%total T (monus-nat T _ _).
%query 1 * (monus-nat (s (s (s z))) (s (s z)) (s z)).
%query 1 * (monus-nat (s (s z)) (s (s (s z))) z).
%% 2 solutions to this one generated from monus-nat/z/1 and monus-nat/z/2.
%query 2 * (monus-nat (s z) (s z) z).
% ===== Relations between natural numbers and booleans =====
nat-eq->bool : nat -> nat -> bool -> type.
%mode nat-eq->bool +N1 +N2 -B.
nat-eq->bool/zz : nat-eq->bool z z true.
nat-eq->bool/zs : nat-eq->bool z (s _) false.
nat-eq->bool/sz : nat-eq->bool (s _) z false.
nat-eq->bool/ss : nat-eq->bool (s N1) (s N2) T
<- nat-eq->bool N1 N2 T.
%worlds () (nat-eq->bool _ _ _).
%total N (nat-eq->bool N _ _).
nat-leq->bool : nat -> nat -> bool -> type.
%mode nat-leq->bool +N1 +N2 -B.
nat-leq->bool/zz : nat-leq->bool z z true.
nat-leq->bool/zs : nat-leq->bool z (s _) true.
nat-leq->bool/sz : nat-leq->bool (s _) z false.
nat-leq->bool/ss : nat-leq->bool (s N1) (s N2) T
<- nat-leq->bool N1 N2 T.
%worlds () (nat-leq->bool _ _ _).
%total N (nat-leq->bool N _ _).
%%% Locations in the language
%%% Jesper Louis Andersen
%% Locations
%% Variables
var : type.
fvar : type.
varlist : type.
varlist/nil : varlist.
varlist/cons : var -> varlist -> varlist.
%%% Peano Style Arithmetic
%%% Jesper Louis Andersen
% ===== Syntax =====
%% Arithmetic expressions
exp : type. %name exp E.
exp/n : nat -> exp.
exp/v : var -> exp.
exp/plus : exp -> exp -> exp.
exp/monus : exp -> exp -> exp.
%{
We need a way to represent lists of expressions when we want to do funcalls.
Hence, we have chosen to represent these as functional lists.
}%
explist : type. %name explist EXPL.
explist/nil : explist.
explist/cons : exp -> explist -> explist.
%%% Length of explists
explist-length : explist -> nat -> type.
%mode explist-length +EL -N.
explist-length/nil : explist-length explist/nil z.
explist-length/cons : explist-length (explist/cons _ EL') (s N)
<- explist-length EL' N.
%worlds () (explist-length _ _).
%total T (explist-length T _).
% ===== Boolean expressions =====
bexp : type. %name bexp B.
bexp/t : bool -> bexp.
bexp/eq : exp -> exp -> bexp.
bexp/leq : exp -> exp -> bexp.
bexp/and : bexp -> bexp -> bexp.
bexp/not : bexp -> bexp.
% ===== Commands =====
cmd : type. %name cmd C.
cmd/skip : cmd.
cmd/assign : var -> exp -> cmd.
; : cmd -> cmd -> cmd. %infix left 500 ;.
cmd/if : bexp -> cmd -> cmd -> cmd.
cmd/while : bexp -> cmd -> cmd.
cmd/funcall : var -> fvar -> explist -> cmd.
cmd/return : exp -> cmd.
% ===== Programs =====
locbind : type. %name locbind LOCB.
locbind/nil : cmd -> locbind.
locbind/cons : (var -> locbind) -> locbind.
parbind : type. %name parbind PARB.
parbind/nil : locbind -> parbind.
parbind/cons : (var -> parbind) -> parbind.
program : type. %name program PGM.
program/main : (fvar -> parbind) -> program.
program/cons : (fvar -> parbind) -> (fvar -> program) -> program.
%% This is mapping from variables to types.
varenv-map : var -> nat -> type.
%mode varenv-map +V -N.
%% Mapping from function variables to function definitions
decenv-map : fvar -> parbind -> type.
%mode decenv-map +F -D.
%%% Implementation of the "store" or "store"
%%% Jesper Louis Andersen
store : type. %name store S.
store/nil : store.
store/cons : nat -> store -> store.
%%% Length of a store
store-length : store -> nat -> type.
%mode store-length +H -N.
store-length/nil : store-length store/nil z.
store-length/cons : store-length (store/cons _ H) (s N)
<- store-length H N.
%worlds () (store-length _ _).
%total H (store-length H _).
%unique store-length +H -1N.
%%% Look up a location in a store
store-find : nat -> store -> nat -> type.
%mode store-find +L +H -E.
store-find/yes : store-find z (store/cons N _) N.
store-find/no : store-find (s K) (store/cons _ H) N
<- store-find K H N.
%worlds () (store-find _ _ _).
%terminates H (store-find _ H _).
%unique store-find +L +H -1E.
store-replace : store -> nat -> nat -> store -> type.
%mode store-replace +H1 +L +N -H2.
store-replace/yes : store-replace (store/cons N1 H) z N2 (store/cons N2 H).
store-replace/no : store-replace (store/cons N1 H) (s K) N2 (store/cons N1 H')
<- store-replace H K N2 H'.
%%worlds () (store-replace _ _ _ _).
%%terminates H (store-replace H _ _ _).
%%unique store-replace +H1 +L +E -1H2.
%%% Append to a store
store-append : store -> nat -> store -> type.
%mode store-append +H1 +N -H2.
store-append/nil : store-append store/nil N (store/cons N store/nil).
store-append/cons : store-append (store/cons N' H) N (store/cons N' H')
<- store-append H N H'.
%worlds () (store-append _ _ _).
%total H (store-append H _ _).
%unique store-append +H1 +N -1H2.
%%% Hack the SML option type for stores
store-option : type.
store-option/none : store-option.
store-option/some : store -> locbind -> store-option.
%%% Formalization of semantics.
%%% Jesper Louis Andersen
% ===== Expression evaluation =====
%%% Arithmetic
eval-exp : exp -> store -> nat -> type.
%mode eval-exp +E +S -N.
eval-exp/n : eval-exp (exp/n N) S N.
eval-exp/v : eval-exp (exp/v V) S N
<- varenv-map V L
<- store-find L S N.
eval-exp/plus : eval-exp (exp/plus E1 E2) S N
<- eval-exp E1 S N1
<- eval-exp E2 S N2
<- plus-nat N1 N2 N.
eval-exp/monus : eval-exp (exp/monus E1 E2) S N
<- eval-exp E1 S N1
<- eval-exp E2 S N2
<- monus-nat N1 N2 N.
%terminates (E X) (eval-exp E _ _) (varenv-map X _).
% %%% Evaluation of arithmetic expressions
eval-explist : explist -> store -> natlist -> type.
%mode eval-explist +EL +S -N.
eval-explist/nil : eval-explist explist/nil S natlist/nil.
eval-explist/cons : eval-explist (explist/cons E EL) S (natlist/cons N NL)
<- eval-exp E S N
<- eval-explist EL S NL.
%terminates E (eval-explist E _ _).
%%% Booleans
eval-bexp : bexp -> store -> bool -> type.
%mode eval-bexp +E +S -B.
eval-bexp/bool : eval-bexp (bexp/t T) S T.
eval-bexp/eq : eval-bexp (bexp/eq E1 E2) S T
<- eval-exp E1 S N1
<- eval-exp E2 S N2
<- nat-eq->bool N1 N2 T.
eval-bexp/leq : eval-bexp (bexp/leq E1 E2) S T
<- eval-exp E1 S N1
<- eval-exp E2 S N2
<- nat-leq->bool N1 N2 T.
eval-bexp/and,1 : eval-bexp (bexp/and B1 B2) S false
<- eval-bexp B1 S false.
eval-bexp/and,2 : eval-bexp (bexp/and B1 B2) S T
<- eval-bexp B1 S true
<- eval-bexp B2 S T.
eval-bexp/not,1 : eval-bexp (bexp/not B) S true
<- eval-bexp B S false.
eval-bexp/not,2 : eval-bexp (bexp/not B) S false
<- eval-bexp B S true.
%terminates E (eval-bexp E _ _).
%%% Commands
%% Results
%{
Commands require a notion of a result because there are multiple possible
outcomes of the command
}%
store^ : type.
store^/wrong : store^.
store^/n : nat -> store^.
store^/store : store -> store^.
%%% Results from functions
fresult : type.
fresult/wrong : fresult.
fresult/n : nat -> fresult.
%%% Conversion
store^->fresult : store^ -> fresult -> type.
%mode store^->fresult +S^ -FR.
store^->fresult/n : store^->fresult (store^/n K) (fresult/n K).
store^->fresult/wrong : store^->fresult store^/wrong fresult/wrong.
store^->fresult/store : store^->fresult (store^/store _) fresult/wrong.
%% Commands
eval-cmd : cmd -> store -> store^ -> type.
%mode eval-cmd +C +S -S^.
bind-locals : locbind -> store -> store^ -> type.
%mode bind-locals +LB +S -S^.
bind-pars : parbind -> natlist -> store -> store^ -> type.
%mode bind-pars +PB +NL +S -S^.
eval-cmd/skip : eval-cmd cmd/skip S (store^/store S).
eval-cmd/assign : eval-cmd (cmd/assign V E) S (store^/store S')
<- varenv-map V L
<- eval-exp E S N
<- store-replace S L N S'.
eval-cmd/semi,1 : eval-cmd (C1 ; C2) S S^
<- eval-cmd C1 S (store^/store S')
<- eval-cmd C2 S' S^.
eval-cmd/semi,2 : eval-cmd (C1 ; C2) S store^/wrong
<- eval-cmd C1 S store^/wrong.
eval-cmd/semi,3 : eval-cmd (C1 ; C2) S (store^/n N)
<- eval-cmd C1 S (store^/n N).
eval-cmd/if,1 : eval-cmd (cmd/if B T E) S R
<- eval-bexp B S true
<- eval-cmd T S R.
eval-cmd/if,2 : eval-cmd (cmd/if B T E) S R
<- eval-bexp B S false
<- eval-cmd E S R.
eval-cmd/while,1 : eval-cmd (cmd/while B C) S R
<- eval-bexp B S true
<- eval-cmd C S (store^/store S')
<- eval-cmd (cmd/while B C) S' R.
eval-cmd/while,2,1 : eval-cmd (cmd/while B C) S store^/wrong
<- eval-bexp B S true
<- eval-cmd C S store^/wrong.
eval-cmd/while,2,2 : eval-cmd (cmd/while B C) S (store^/n N)
<- eval-bexp B S true
<- eval-cmd C S (store^/n N).
eval-cmd/while,3 : eval-cmd (cmd/while B C) S (store^/store S)
<- eval-bexp B S false.
eval-cmd/funcall,1 : eval-cmd (cmd/funcall X F EL) S (store^/store S')
<- eval-explist EL S NL
<- decenv-map F C
<- bind-pars C NL store/nil R
<- store^->fresult R (fresult/n N)
<- varenv-map X L
<- store-replace S L N S'.
eval-cmd/funcall,2 : eval-cmd (cmd/funcall X F EL) S store^/wrong
<- eval-explist EL S NL
<- decenv-map F C
<- bind-pars C NL store/nil R
<- store^->fresult R fresult/wrong.
eval-cmd/return : eval-cmd (cmd/return E) S (store^/n N)
<- eval-exp E S N.
bind-locals/nil : bind-locals (locbind/nil C) S R
<- eval-cmd C S R.
bind-locals/cons : bind-locals (locbind/cons ([y : var] C y)) S R
<- store-length S L
<- store-append S z S'
<- ({x : var} varenv-map x L -> bind-locals (C x) S' R).
bind-pars/nil : bind-pars (parbind/nil LB) natlist/nil S R
<- bind-locals LB S R.
bind-pars/cons : bind-pars (parbind/cons ([x] C x)) (natlist/cons N NL) S R
<- store-length S L
<- store-append S N S'
<- ({x : var} varenv-map x L -> bind-pars (C x) NL S' R).
bind-pars/f1 : bind-pars (parbind/cons ([x] C x)) natlist/nil S store^/wrong.
bind-pars/f2 : bind-pars (parbind/nil LB) (natlist/cons _ _) S store^/wrong.
eval-program : program -> natlist -> store^ -> type.
eval-program/main : eval-program (program/main ([f] D f)) NL R
<- ({f : fvar} decenv-map f (D f) -> bind-pars (D f) NL store/nil R).
eval-program/cons : eval-program (program/cons ([f] D f) ([f] P f)) NL R
<- ({f : fvar} decenv-map f (D f)
-> eval-program (P f) NL R).
eval-p : program -> natlist -> fresult -> type.
eval-p,1 : eval-p P NL FL
<- eval-program P NL S
<- store^->fresult S FR.%%% Program definitions
%%% Jesper Louis Andersen
%% Before trying our luck on the programs A and B, we do a series of queries
%% on much simpler structures for test purposes.
%% Arithmetic numbers
zero = z.
one = s z.
two = s (s z).
three = s two.
four = s three.
five = s four.
six = s five.
seven = s six.
%define twelf : nat = N
%solve twelf_compute : plus-nat six six N.
%define twentyfour : nat = K
%solve twentyfour_compute : plus-nat twelf twelf K.
test_1 : exp = (exp/plus (exp/n three) (exp/n four)).
%query 1 * (eval-exp test_1 store/nil seven).
test_2 : bexp = (bexp/eq (exp/n four) (exp/n four)).
test_2_1 : bexp = (bexp/not (bexp/t false)).
%query 1 * (eval-bexp test_2 store/nil true).
%query 1 * (eval-bexp test_2_1 store/nil true).
test_3 : (bool -> cmd) = [b] (cmd/if (bexp/t b) (cmd/return (exp/n three))
(cmd/return (exp/n four))).
%query 1 * (eval-cmd (test_3 true) store/nil (store^/n three)).
%query 1 * (eval-cmd (test_3 false) store/nil (store^/n four)).
test_4_1 : parbind = (parbind/nil (locbind/nil
(cmd/return (exp/n three)))).
%query 1 * (store-length store/nil z).
test_4_2 : parbind = (parbind/nil (locbind/cons [x] (locbind/nil
(cmd/assign x (exp/n five);
cmd/return (exp/v x))))).
test_5 : parbind = (parbind/cons [x] (parbind/nil (locbind/nil
(cmd/return (exp/v x))))).
test_5_i = (natlist/cons three natlist/nil).
test_5_1 : parbind = (parbind/cons [x] (parbind/nil (locbind/nil
(cmd/skip)))).
test_6 : program = program/main ([fac] test_5).
%query 1 1 (eval-p test_6 natlist/nil fresult/wrong).
%query 1 1 (eval-p test_6 (natlist/cons three natlist/nil) (fresult/n three)).
test_7 : program = program/main ([callme]
(parbind/cons [x] (parbind/nil (locbind/nil (cmd/if
(bexp/eq (exp/v x) (exp/n z))
(cmd/return (exp/n two))
(cmd/funcall x callme (explist/cons
(exp/monus (exp/v x)
(exp/n one)) explist/nil);
cmd/return (exp/v x))))))).
%query 1 1 (eval-p test_7 (natlist/cons two natlist/nil) (fresult/n two)).
%% Tests of the store...
%define s_1 = R
%solve s_1_compute : (store-append store/nil four R).
%query 1 1 (store-append store/nil four (store/cons four store/nil)).
%% Testing multiplication
program_mul = program/main
([mul]
(parbind/cons [x] (parbind/cons [y] (parbind/nil
(locbind/cons [r] (locbind/nil
((cmd/while (bexp/not (bexp/eq (exp/v x) (exp/n z)))
((cmd/assign r (exp/plus (exp/v r) (exp/v y)));
(cmd/assign x (exp/monus (exp/v x) (exp/n one)))));
(cmd/return (exp/v r))))))))).
%query 1 1 (eval-p program_mul
(natlist/cons one
(natlist/cons one
natlist/nil)) (fresult/n one)).
%% Project programs follow....
program_a = program/cons
([mul]
(parbind/cons [x] (parbind/cons [y] (parbind/nil
(locbind/cons [r] (locbind/nil
((cmd/while (bexp/not (bexp/eq (exp/v x) (exp/n z)))
((cmd/assign r (exp/plus (exp/v r) (exp/v y)));
(cmd/assign x (exp/monus (exp/v x) (exp/n one)))));
(cmd/return (exp/v r)))))))))
([mul] program/main ([fac] (parbind/cons [x] (parbind/nil
(locbind/cons [r] (locbind/nil
(cmd/if (bexp/eq (exp/v x) (exp/n z))
(cmd/return (exp/n (s z)))
((cmd/funcall r fac (explist/cons
(exp/monus (exp/v x)
(exp/n (s z)))
explist/nil));
(cmd/funcall r mul (explist/cons (exp/v r)
(explist/cons (exp/v x)
explist/nil))));
(cmd/return (exp/v r))))))))).
%query 1 * (eval-p program_a (natlist/cons z natlist/nil) (fresult/n one)).
%query 1 1 (eval-p program_a (natlist/cons one natlist/nil)
(fresult/n one)).
%query 1 1 (eval-p program_a (natlist/cons four natlist/nil) (fresult/n twentyfour)).
program_b : program =
(program/main [fun]
(parbind/cons [x] (parbind/nil
(locbind/nil
(cmd/if (bexp/eq (exp/v x) (exp/n z))
cmd/skip
(cmd/if (bexp/eq (exp/v x) (exp/n one))
(cmd/funcall x fun explist/nil)
(cmd/if (bexp/eq (exp/v x) (exp/n two))
(cmd/funcall x fun (explist/cons
(exp/n z) (explist/cons (exp/v x)
explist/nil)))
(cmd/return (exp/monus (exp/v x) (exp/n four)))))))))).
eval_program_b = [n : nat] [r : fresult] (eval-p program_b
(natlist/cons n natlist/nil) r).
%query 1 1 (eval-p program_b (natlist/cons z natlist/nil) fresult/wrong).
%query 1 1 (eval-p program_b (natlist/cons one natlist/nil) fresult/wrong).
%query 1 1 (eval-p program_b (natlist/cons two natlist/nil) fresult/wrong).
%query 1 1 (eval-p program_b (natlist/cons three natlist/nil)
(fresult/n z)).
%query 1 1 (eval-p program_b (natlist/cons four natlist/nil)
(fresult/n z)).
%query 1 1 (eval-p program_b (natlist/cons five natlist/nil)
(fresult/n one)).%%% Language type system
%%% Jesper Louis Andersen
%% Safety: Always encounters a return.
must-return : cmd -> type.
%mode must-return +C.
must-return/semi,1 : must-return (C1 ; C2)
<- must-return C1.
must-return/semi,2 : must-return (C1 ; C2)
<- must-return C2.
must-return/if : must-return (cmd/if B C1 C2)
<- must-return C1
<- must-return C2.
must-return/return : must-return (cmd/return E).
%% Arity environments
arityenv : fvar -> nat -> type.
%mode arityenv +F -N.
%% right-arguments checks that funcall has the right number of arguments.
right-arguments : cmd -> type.
%mode right-arguments +C.
right-arguments/skip : right-arguments cmd/skip.
right-arguments/assign : right-arguments (cmd/assign _ _).
right-arguments/semi : right-arguments (C1 ; C2)
<- right-arguments C1
<- right-arguments C2.
right-arguments/if : right-arguments (cmd/if B C1 C2)
<- right-arguments C1
<- right-arguments C2.
right-arguments/while : right-arguments (cmd/while B C)
<- right-arguments C.
right-arguments/funcall : right-arguments (cmd/funcall V F EL)
<- arityenv F K
<- explist-length EL K.
right-arguments/return : right-arguments (cmd/return E).
check-command : cmd -> type.
check-command,1 : check-command C
<- must-return C
<- right-arguments C.
check-locbind : fvar -> locbind -> nat -> type.
check-locbind/cons : check-locbind F (locbind/cons ([x] R x)) K
<- ({x : var} check-locbind F (R x) K).
check-locbind/nil : check-locbind F (locbind/nil C) K
<- check-command C.
check-parbind : fvar -> parbind -> nat -> nat -> type.
check-parbind/cons : check-parbind F (parbind/cons ([x] R x)) K (s N)
<- ({x : var} check-parbind F (R x) (s K) N).
check-parbind/nil : check-parbind F (parbind/nil LB) N z
<- check-locbind F LB N.
check-program : program -> nat -> type.
check-program/main : check-program (program/main ([f : fvar] D f)) K
<- ({f : fvar} arityenv f K -> check-parbind f (D f) z K).
check-program/cons : check-program (program/cons ([f] D f) ([f] P f)) N
<- ({f : fvar} arityenv f K -> check-parbind f (D f) z K)
<- ({f : fvar} arityenv f K -> check-program (P f) N).
%query 1 1 (check-program test_6 one).
%query 1 1 (check-program test_7 one).
%query 1 1 (check-program program_a one).
%%% The soundness theorem
%%% Jesper Louis Andersen
%% A little lemma on expression lists
explist-lemma-1 : (eval-explist EL S NL) -> (explist-length EL K)
-> (natlist-size NL K) -> type.
%mode explist-lemma-1 +EL +EEL -NLS.
explist-lemma-1/nil : explist-lemma-1
eval-explist/nil
explist-length/nil
natlist-size/nil.
explist-lemma-1/cons : explist-lemma-1
(eval-explist/cons EPL EP)
(explist-length/cons EPL')
(natlist-size/cons NLS')
<- explist-lemma-1 EPL EPL' NLS'.
%% Bind together a function definition and its checked function body
checkenv : (arityenv F K) -> (decenv-map F D) ->
(check-parbind F D z K) -> type.
%mode checkenv +AE +DECM -CP.
%% Contexts we are proving in.
%block varenv-block : some {L}
block {x : var} {vm : varenv-map x L}.
%block checkenv-block : some {D : fvar -> parbind} {K} {CPB}
block {f : fvar} {dm : decenv-map f (D f)} {ae : arityenv f K}
{ce : checkenv ae dm (CPB f ae)}.
wrong-or-return : store^ -> type.
wrong-or-return/wrong : wrong-or-return store^/wrong.
wrong-or-return/res : wrong-or-return (store^/n N).
%% A contradiction on the form of the wrong-or-return.
rs-contradict-lemma-1 : wrong-or-return (store^/store S) -> void -> type.
%mode rs-contradict-lemma-1 +WR -V.
%worlds () (rs-contradict-lemma-1 _ _).
%total T (rs-contradict-lemma-1 T _).
rs-contradict-1-void-any : {S^} void -> (wrong-or-return S^) -> type.
%mode rs-contradict-1-void-any +S^ +V -WR.
%worlds () (rs-contradict-1-void-any _ _ _).
%total T (rs-contradict-1-void-any _ T _).
store-or-return : store^ -> type.
store-or-return/store : store-or-return (store^/store S).
store-or-return/res : store-or-return (store^/n N).
sresult-res : store^ -> type.
sresult-res/res : sresult-res (store^/n N).
sr-contradict : (sresult-res (store^/wrong)) -> void -> type.
%mode sr-contradict +SR -V.
%worlds () (sr-contradict _ _).
%total T (sr-contradict T _).
sr-contradict-2 : (sresult-res (store^/store _)) -> void -> type.
%mode sr-contradict-2 +SR -V.
%worlds () (sr-contradict-2 _ _).
%total T (sr-contradict-2 T _).
void-s-or-r : {S^} void -> (store-or-return S^) -> type.
%mode void-s-or-r +S^ +V -SR.
%worlds () (void-s-or-r _ _ _).
%total T (void-s-or-r _ T _).
void-sr : {S^} void -> (sresult-res S^) -> type.
%mode void-sr +S^ +V -SR.
%worlds () (void-sr _ _ _).
%total T (void-sr _ T _).
void-s : {N} void -> (sresult-res (store^/n N)) -> type.
%mode void-s +N +V -R.
%worlds () (void-s _ _ _).
%total T (void-s _ T _).
result-coerce : (store-or-return S^) -> (wrong-or-return S^)
-> (sresult-res S^) -> type.
%mode result-coerce +SR +WR -S.
sresult->sr : (sresult-res S^) -> (store-or-return S^) -> type.
%mode sresult->sr +S -S'.
sresult->sr/res : sresult->sr sresult-res/res store-or-return/res.
%worlds () (sresult->sr _ _).
%total T (sresult->sr T _).
result-cource/ss : result-coerce
store-or-return/res
wrong-or-return/res
sresult-res/res.
%worlds () (result-coerce _ _ _).
%total T (result-coerce T _ _).
return-soundness : (must-return C) -> (eval-cmd C S S^) -> (wrong-or-return S^) -> type.
%mode return-soundness +MR +EP -S.
return-soundness/return : return-soundness
must-return/return
(eval-cmd/return CP)
wrong-or-return/res.
return-soundness/if,1 : return-soundness
(must-return/if RP2 RP1)
(eval-cmd/if,1 CP BP)
R
<- return-soundness RP1 CP R.
return-soundness/if,2 : return-soundness
(must-return/if RP2 RP1)
(eval-cmd/if,2 CP BP)
R
<- return-soundness RP2 CP R.
return-soundness/semi,3 : return-soundness
(must-return/semi,1 RP)
(eval-cmd/semi,3 CP)
R
<- return-soundness RP CP R.
return-soundness/semi,2 : return-soundness
(must-return/semi,1 RP)
(eval-cmd/semi,2 CP)
R
<- return-soundness RP CP R.
return-soundness/semi,1 : return-soundness
(must-return/semi,2 RP)
(eval-cmd/semi,1 CP2 CP1)
R
<- return-soundness RP CP2 R.
return-soundness/semi,2,2 : return-soundness
(must-return/semi,2 RP)
(eval-cmd/semi,2 CP)
wrong-or-return/wrong.
return-soundness/semi,2,3 : return-soundness
(must-return/semi,2 RP)
(eval-cmd/semi,3 CP)
wrong-or-return/res.
return-soundness/semi,1,1,r : return-soundness
(must-return/semi,1 RP)
(eval-cmd/semi,1 CP2 CP1)
wrong-or-return/res.
return-soundness/semi,1,1,w : return-soundness
(must-return/semi,1 RP)
(eval-cmd/semi,1 CP2 CP1)
wrong-or-return/wrong.
return-soundness/semi,1,1 : return-soundness
(must-return/semi,1 RP)
(eval-cmd/semi,1 CP2 CP1)
Q
<- return-soundness RP CP1 R
<- rs-contradict-lemma-1 R V
<- rs-contradict-1-void-any _ V Q.
argument-soundness : (eval-cmd C S S^) -> (right-arguments C)
-> (store-or-return S^) -> type.
%mode argument-soundness +C +RA -S.
parbind-soundness : {F} (bind-pars PB NL S S^)
-> (check-parbind F PB N K) -> (natlist-size NL K)
-> (sresult-res S^) -> type.
%mode parbind-soundness +F +BP +CB +NLS -SR.
argument-soundness/return : argument-soundness
(eval-cmd/return EP)
right-arguments/return
store-or-return/res.
argument-soundness/skip : argument-soundness
eval-cmd/skip
right-arguments/skip
store-or-return/store.
argument-soundness/while,1 : argument-soundness
(eval-cmd/while,1 CP2 CP1 BP)
RA
R
<- argument-soundness CP2 RA R.
argument-soundness/while,3 : argument-soundness
(eval-cmd/while,3 BP)
RA
store-or-return/store.
argument-soundness/while,2,2 : argument-soundness
(eval-cmd/while,2,2 CP BP)
RA
store-or-return/res.
argument-soundness/while,2,1 : argument-soundness
(eval-cmd/while,2,1 CP BP)
(right-arguments/while AP)
R
<- argument-soundness CP AP R.
argument-soundness/if,1 : argument-soundness
(eval-cmd/if,1 CP BP)
(right-arguments/if AP2 AP1)
R
<- argument-soundness CP AP1 R.
argument-soundness/if,2 : argument-soundness
(eval-cmd/if,2 CP BP)
(right-arguments/if AP2 AP1)
R
<- argument-soundness CP AP2 R.
argument-soundness/semi,1 : argument-soundness
(eval-cmd/semi,1 CP2 CP1)
(right-arguments/semi AP2 AP1)
R
<- argument-soundness CP2 AP2 R.
argument-soundness/semi,2 : argument-soundness
(eval-cmd/semi,2 CP)
(right-arguments/semi AP2 AP1)
R
<- argument-soundness CP AP1 R.
argument-soundness/semi,3 : argument-soundness
(eval-cmd/semi,3 CP)
(right-arguments/semi AP2 AP1)
store-or-return/res.
argument-soundness/assign : argument-soundness
(eval-cmd/assign SR EP VM)
right-arguments/assign
store-or-return/store.
argument-soundness/funcall,1 : argument-soundness
(eval-cmd/funcall,1 _ _ _ _ _ _)
(right-arguments/funcall EELL AE)
store-or-return/store.
argument-soundness/funcall,2,1 : argument-soundness
(eval-cmd/funcall,2 SRCONV BP DECENVM EVALEL)
(right-arguments/funcall EVALLL (AE : arityenv _ K))
Q
<- explist-lemma-1 EVALEL EVALLL (NLS : natlist-size _ K)
<- checkenv AE DECENVM CPB
<- parbind-soundness F BP CPB NLS R
<- sr-contradict R V
<- void-s-or-r _ V Q.
argument-soundness/funcall,2,2 : argument-soundness
(eval-cmd/funcall,2 SR BP DECM EEEL)
(right-arguments/funcall EELL AE)
Q
<- explist-lemma-1 EEEL EELL NLS
<- checkenv AE DECM CPB
<- parbind-soundness F BP CPB NLS R
<- sr-contradict-2 R V
<- void-s-or-r _ V Q.
%%% Formulation of main soundness theorem.
fresult-res : fresult -> type.
fresult-res/res : fresult-res (fresult/n N).
command-soundness :
(eval-cmd C S S^) -> (check-command C) -> (sresult-res S^) -> type.
%mode command-soundness +EP +CP -SR.
command-soundness,1 : command-soundness
EP
(check-command,1 RA MR)
R
<- return-soundness MR EP P
<- argument-soundness EP RA Q
<- result-coerce Q P R.
localbind-soundness : {F : fvar} (bind-locals LB S S^) -> (check-locbind F LB K)
-> (sresult-res S^) -> type.
%mode localbind-soundness +F +BL +CP -SR.
localbind-soundness/nil : localbind-soundness F
(bind-locals/nil EP)
(check-locbind/nil CP)
R
<- command-soundness EP CP R.
localbind-soundness/cons : localbind-soundness F
(bind-locals/cons BL SA SL)
(check-locbind/cons RP)
R
<- ({x : var} {vm : varenv-map x L}
localbind-soundness F (BL x vm) (RP x) R).
parbind-soundness/nil : parbind-soundness F
(bind-pars/nil BL)
(check-parbind/nil CL)
natlist-size/nil
R
<- localbind-soundness F BL CL R.
parbind-soundness/cons : parbind-soundness F
(bind-pars/cons BP SA SL)
(check-parbind/cons CP)
(natlist-size/cons NLS')
R
<- ({x : var} {vm : varenv-map x L}
parbind-soundness F (BP x vm) (CP x) NLS' R).
program-soundness : (eval-program P NL R) -> (natlist-size NL K) ->
(check-program P K) -> (sresult-res R) -> type.
%mode program-soundness +EP +NLS +CP -R.
program-soundness/main,1 : program-soundness
(eval-program/main EP)
(NLS : natlist-size _ K)
(check-program/main CP)
Q
<- ({f : fvar} {dm : decenv-map f (D f)} {ae : arityenv f K}
{ce : checkenv ae dm (CP f ae)}
parbind-soundness f (EP f dm) (CP f ae) NLS Q).
program-soundness/cons : program-soundness
(eval-program/cons RP)
NLS
(check-program/cons CP CPB)
S
<- ({f : fvar} {dm : decenv-map f (D f)} {ae : arityenv f K}
checkenv ae dm ((CPB f ae) : check-parbind _ _ _ K) ->
program-soundness (RP f dm) NLS (CP f ae) S).
%worlds (varenv-block) (explist-lemma-1 _ _ _).
%total E (explist-lemma-1 E _ _).
%worlds (varenv-block | checkenv-block) (return-soundness _ _ _).
%total E (return-soundness E _ _).
%worlds (varenv-block | checkenv-block)
(argument-soundness _ _ _)
(command-soundness _ _ _)(checkenv _ _ _)
(parbind-soundness _ _ _ _ _)(program-soundness _ _ _ _)
(localbind-soundness _ _ _ _).
%total (T E E1 E2 E3 E4)
(argument-soundness E4 _ _)
(command-soundness E3 _ _)(checkenv _ T _)
(localbind-soundness _ E2 _ _)
(parbind-soundness _ E1 _ _ _)
(program-soundness E _ _ _).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment