Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
C
cpdt
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
research
cpdt
Commits
77382d81
Commit
77382d81
authored
Aug 01, 2012
by
Adam Chlipala
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Undo some overzealous vspace tweaks
parent
537bf93d
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
51 additions
and
42 deletions
+51
-42
Coinductive.v
src/Coinductive.v
+1
-1
InductiveTypes.v
src/InductiveTypes.v
+19
-19
Predicates.v
src/Predicates.v
+8
-8
StackMachine.v
src/StackMachine.v
+11
-2
Subset.v
src/Subset.v
+12
-12
No files found.
src/Coinductive.v
View file @
77382d81
...
...
@@ -29,7 +29,7 @@ We spent some time in the last chapter discussing the %\index{Curry-Howard corre
Fixpoint
bad
(
u
:
unit
)
:
P
:=
bad
u
.
]]
%
\
smallskip
{}%
This
would
leave
us
with
[
bad
tt
]
as
a
proof
of
[
P
]
.
This
would
leave
us
with
[
bad
tt
]
as
a
proof
of
[
P
]
.
There
are
also
algorithmic
considerations
that
make
universal
termination
very
desirable
.
We
have
seen
how
tactics
like
[
reflexivity
]
compare
terms
up
to
equivalence
under
computational
rules
.
Calls
to
recursive
,
pattern
-
matching
functions
are
simplified
automatically
,
with
no
need
for
explicit
proof
steps
.
It
would
be
very
hard
to
hold
onto
that
kind
of
benefit
if
it
became
possible
to
write
non
-
terminating
programs
;
we
would
be
running
smack
into
the
halting
problem
.
...
...
src/InductiveTypes.v
View file @
77382d81
This diff is collapsed.
Click to expand it.
src/Predicates.v
View file @
77382d81
...
...
@@ -45,7 +45,7 @@ Print True.
Inductive
True
:
Prop
:=
I
:
True
]]
%
\
smallskip
{}%
Recall
that
[
unit
]
is
the
type
with
only
one
value
,
and
[
True
]
is
the
proposition
that
always
holds
.
Despite
this
superficial
difference
between
the
two
concepts
,
in
both
cases
we
can
use
the
same
inductive
definition
mechanism
.
The
connection
goes
further
than
this
.
We
see
that
we
arrive
at
the
definition
of
[
True
]
by
replacing
[
unit
]
by
[
True
]
,
[
tt
]
by
[
I
]
,
and
[
Set
]
by
[
Prop
]
.
The
first
two
of
these
differences
are
superficial
changes
of
names
,
while
the
third
difference
is
the
crucial
one
for
separating
programs
from
proofs
.
A
term
[
T
]
of
type
[
Set
]
is
a
type
of
programs
,
and
a
term
of
type
[
T
]
is
a
program
.
A
term
[
T
]
of
type
[
Prop
]
is
a
logical
proposition
,
and
its
proofs
are
of
type
[
T
]
.
Chapter
12
goes
into
more
detail
about
the
theoretical
differences
between
[
Prop
]
and
[
Set
]
.
For
now
,
we
will
simply
follow
common
intuitions
about
what
a
proof
is
.
Recall
that
[
unit
]
is
the
type
with
only
one
value
,
and
[
True
]
is
the
proposition
that
always
holds
.
Despite
this
superficial
difference
between
the
two
concepts
,
in
both
cases
we
can
use
the
same
inductive
definition
mechanism
.
The
connection
goes
further
than
this
.
We
see
that
we
arrive
at
the
definition
of
[
True
]
by
replacing
[
unit
]
by
[
True
]
,
[
tt
]
by
[
I
]
,
and
[
Set
]
by
[
Prop
]
.
The
first
two
of
these
differences
are
superficial
changes
of
names
,
while
the
third
difference
is
the
crucial
one
for
separating
programs
from
proofs
.
A
term
[
T
]
of
type
[
Set
]
is
a
type
of
programs
,
and
a
term
of
type
[
T
]
is
a
program
.
A
term
[
T
]
of
type
[
Prop
]
is
a
logical
proposition
,
and
its
proofs
are
of
type
[
T
]
.
Chapter
12
goes
into
more
detail
about
the
theoretical
differences
between
[
Prop
]
and
[
Set
]
.
For
now
,
we
will
simply
follow
common
intuitions
about
what
a
proof
is
.
The
type
[
unit
]
has
one
value
,
[
tt
]
.
The
type
[
True
]
has
one
proof
,
[
I
]
.
Why
distinguish
between
these
two
types
?
Many
people
who
have
read
about
Curry
-
Howard
in
an
abstract
context
and
not
put
it
to
use
in
proof
engineering
answer
that
the
two
types
in
fact
_
should
not_
be
distinguished
.
There
is
a
certain
aesthetic
appeal
to
this
point
of
view
,
but
I
want
to
argue
that
it
is
best
to
treat
Curry
-
Howard
very
loosely
in
practical
proving
.
There
are
Coq
-
specific
reasons
for
preferring
the
distinction
,
involving
efficient
compilation
and
avoidance
of
paradoxes
in
the
presence
of
classical
math
,
but
I
will
argue
that
there
is
a
more
general
principle
that
should
lead
us
to
avoid
conflating
programming
and
proving
.
...
...
@@ -87,7 +87,7 @@ We have also already seen the definition of [True]. For a demonstration of a lo
Inductive
False
:
Prop
:=
]]
%
\
smallskip
{}%
We
can
conclude
anything
from
[
False
]
,
doing
case
analysis
on
a
proof
of
[
False
]
in
the
same
way
we
might
do
case
analysis
on
,
say
,
a
natural
number
.
Since
there
are
no
cases
to
consider
,
any
such
case
analysis
succeeds
immediately
in
proving
the
goal
.
*
)
We
can
conclude
anything
from
[
False
]
,
doing
case
analysis
on
a
proof
of
[
False
]
in
the
same
way
we
might
do
case
analysis
on
,
say
,
a
natural
number
.
Since
there
are
no
cases
to
consider
,
any
such
case
analysis
succeeds
immediately
in
proving
the
goal
.
*
)
Theorem
False_imp
:
False
->
2
+
2
=
5.
(
*
begin
thide
*
)
...
...
@@ -129,7 +129,7 @@ We have also already seen the definition of [True]. For a demonstration of a lo
:
Prop
->
Prop
]]
%
\
smallskip
{}%
We
see
that
[
not
]
is
just
shorthand
for
implication
of
[
False
]
.
We
can
use
that
fact
explicitly
in
proofs
.
The
syntax
[
~
P
]
expands
to
[
not
P
]
.
*
)
We
see
that
[
not
]
is
just
shorthand
for
implication
of
[
False
]
.
We
can
use
that
fact
explicitly
in
proofs
.
The
syntax
[
~
P
]
expands
to
[
not
P
]
.
*
)
Theorem
arith_neq
'
:
~
(
2
+
2
=
5
)
.
(
*
begin
thide
*
)
...
...
@@ -151,7 +151,7 @@ We have also already seen the definition of [True]. For a demonstration of a lo
Inductive
and
(
A
:
Prop
)
(
B
:
Prop
)
:
Prop
:=
conj
:
A
->
B
->
A
/
\
B
]]
%
\
smallskip
{}%
The
interested
reader
can
check
that
[
and
]
has
a
Curry
-
Howard
equivalent
called
%
\
index
{
Gallina
terms
!
prod
}%
[
prod
]
,
the
type
of
pairs
.
However
,
it
is
generally
most
convenient
to
reason
about
conjunction
using
tactics
.
An
explicit
proof
of
commutativity
of
[
and
]
illustrates
the
usual
suspects
for
such
tasks
.
The
operator
[
/
\
]
is
an
infix
shorthand
for
[
and
]
.
*
)
The
interested
reader
can
check
that
[
and
]
has
a
Curry
-
Howard
equivalent
called
%
\
index
{
Gallina
terms
!
prod
}%
[
prod
]
,
the
type
of
pairs
.
However
,
it
is
generally
most
convenient
to
reason
about
conjunction
using
tactics
.
An
explicit
proof
of
commutativity
of
[
and
]
illustrates
the
usual
suspects
for
such
tasks
.
The
operator
[
/
\
]
is
an
infix
shorthand
for
[
and
]
.
*
)
Theorem
and_comm
:
P
/
\
Q
->
Q
/
\
P
.
...
...
@@ -199,7 +199,7 @@ subgoal 2 is
or_introl
:
A
->
A
\
/
B
|
or_intror
:
B
->
A
\
/
B
]]
%
\
smallskip
{}%
We
see
that
there
are
two
ways
to
prov
a
disjunction
:
prove
the
first
disjunct
or
prove
the
second
.
The
Curry
-
Howard
analogue
of
this
is
the
Coq
%
\
index
{
Gallina
terms
!
sum
}%
[
sum
]
type
.
We
can
demonstrate
the
main
tactics
here
with
another
proof
of
commutativity
.
*
)
We
see
that
there
are
two
ways
to
prov
a
disjunction
:
prove
the
first
disjunct
or
prove
the
second
.
The
Curry
-
Howard
analogue
of
this
is
the
Coq
%
\
index
{
Gallina
terms
!
sum
}%
[
sum
]
type
.
We
can
demonstrate
the
main
tactics
here
with
another
proof
of
commutativity
.
*
)
Theorem
or_comm
:
P
\
/
Q
->
Q
\
/
P
.
...
...
@@ -373,7 +373,7 @@ We will see more about Coq's program extraction facility in a later chapter. Ho
ex_intro
:
forall
x
:
A
,
P
x
->
ex
P
]]
%
\
smallskip
{}%
The
family
[
ex
]
is
parameterized
by
the
type
[
A
]
that
we
quantify
over
,
and
by
a
predicate
[
P
]
over
[
A
]
s
.
We
prove
an
existential
by
exhibiting
some
[
x
]
of
type
[
A
]
,
along
with
a
proof
of
[
P
x
]
.
As
usual
,
there
are
tactics
that
save
us
from
worrying
about
the
low
-
level
details
most
of
the
time
.
We
use
the
equality
operator
[
=
]
,
which
,
depending
on
the
settings
in
which
they
learned
logic
,
different
people
will
say
either
is
or
is
not
part
of
first
-
order
logic
.
For
our
purposes
,
it
is
.
*
)
The
family
[
ex
]
is
parameterized
by
the
type
[
A
]
that
we
quantify
over
,
and
by
a
predicate
[
P
]
over
[
A
]
s
.
We
prove
an
existential
by
exhibiting
some
[
x
]
of
type
[
A
]
,
along
with
a
proof
of
[
P
x
]
.
As
usual
,
there
are
tactics
that
save
us
from
worrying
about
the
low
-
level
details
most
of
the
time
.
We
use
the
equality
operator
[
=
]
,
which
,
depending
on
the
settings
in
which
they
learned
logic
,
different
people
will
say
either
is
or
is
not
part
of
first
-
order
logic
.
For
our
purposes
,
it
is
.
*
)
Theorem
exist1
:
exists
x
:
nat
,
x
+
1
=
2.
(
*
begin
thide
*
)
...
...
@@ -463,7 +463,7 @@ Print eq.
Inductive
eq
(
A
:
Type
)
(
x
:
A
)
:
A
->
Prop
:=
eq_refl
:
x
=
x
]]
%
\
smallskip
{}%
Behind
the
scenes
,
uses
of
infix
[
=
]
are
expanded
to
instances
of
[
eq
]
.
We
see
that
[
eq
]
has
both
a
parameter
[
x
]
that
is
fixed
and
an
extra
unnamed
argument
of
the
same
type
.
The
type
of
[
eq
]
allows
us
to
state
any
equalities
,
even
those
that
are
provably
false
.
However
,
examining
the
type
of
equality
'
s
sole
constructor
[
eq_refl
]
,
we
see
that
we
can
only
_
prove_
equality
when
its
two
arguments
are
syntactically
equal
.
This
definition
turns
out
to
capture
all
of
the
basic
properties
of
equality
,
and
the
equality
-
manipulating
tactics
that
we
have
seen
so
far
,
like
[
reflexivity
]
and
[
rewrite
]
,
are
implemented
treating
[
eq
]
as
just
another
inductive
type
with
a
well
-
chosen
definition
.
Another
way
of
stating
that
definition
is
:
equality
is
defined
as
the
least
reflexive
relation
.
Behind
the
scenes
,
uses
of
infix
[
=
]
are
expanded
to
instances
of
[
eq
]
.
We
see
that
[
eq
]
has
both
a
parameter
[
x
]
that
is
fixed
and
an
extra
unnamed
argument
of
the
same
type
.
The
type
of
[
eq
]
allows
us
to
state
any
equalities
,
even
those
that
are
provably
false
.
However
,
examining
the
type
of
equality
'
s
sole
constructor
[
eq_refl
]
,
we
see
that
we
can
only
_
prove_
equality
when
its
two
arguments
are
syntactically
equal
.
This
definition
turns
out
to
capture
all
of
the
basic
properties
of
equality
,
and
the
equality
-
manipulating
tactics
that
we
have
seen
so
far
,
like
[
reflexivity
]
and
[
rewrite
]
,
are
implemented
treating
[
eq
]
as
just
another
inductive
type
with
a
well
-
chosen
definition
.
Another
way
of
stating
that
definition
is
:
equality
is
defined
as
the
least
reflexive
relation
.
Returning
to
the
example
of
[
isZero
]
,
we
can
see
how
to
work
with
hypotheses
that
use
this
predicate
.
*
)
...
...
@@ -531,7 +531,7 @@ isZero_ind
:
forall
P
:
nat
->
Prop
,
P
0
->
forall
n
:
nat
,
isZero
n
->
P
n
]]
%
\
smallskip
{}%
In
our
last
proof
script
,
[
destruct
]
chose
to
instantiate
[
P
]
as
[
fun
n
=>
S
n
+
S
n
=
S
(
S
(
S
(
S
n
)))]
.
You
can
verify
for
yourself
that
this
specialization
of
the
principle
applies
to
the
goal
and
that
the
hypothesis
[
P
0
]
then
matches
the
subgoal
we
saw
generated
.
If
you
are
doing
a
proof
and
encounter
a
strange
transmutation
like
this
,
there
is
a
good
chance
that
you
should
go
back
and
replace
a
use
of
[
destruct
]
with
[
inversion
]
.
*
)
In
our
last
proof
script
,
[
destruct
]
chose
to
instantiate
[
P
]
as
[
fun
n
=>
S
n
+
S
n
=
S
(
S
(
S
(
S
n
)))]
.
You
can
verify
for
yourself
that
this
specialization
of
the
principle
applies
to
the
goal
and
that
the
hypothesis
[
P
0
]
then
matches
the
subgoal
we
saw
generated
.
If
you
are
doing
a
proof
and
encounter
a
strange
transmutation
like
this
,
there
is
a
good
chance
that
you
should
go
back
and
replace
a
use
of
[
destruct
]
with
[
inversion
]
.
*
)
(
*
begin
hide
*
)
...
...
src/StackMachine.v
View file @
77382d81
...
...
@@ -103,6 +103,9 @@ Eval simpl in expDenote (Binop Plus (Const 2) (Const 2)).
Eval
simpl
in
expDenote
(
Binop
Times
(
Binop
Plus
(
Const
2
)
(
Const
2
))
(
Const
7
))
.
(
**
[
=
28
:
nat
]
*
)
(
**
%
\
smallskip
{}%
Nothing
too
surprising
goes
on
here
,
so
we
are
ready
to
move
on
to
the
target
language
of
our
compiler
.
*
)
(
**
**
Target
Language
*
)
(
**
We
will
compile
our
source
programs
onto
a
simple
stack
machine
,
whose
syntax
is
:
*
)
...
...
@@ -140,6 +143,8 @@ Fixpoint progDenote (p : prog) (s : stack) : option stack :=
end
end
.
(
**
With
the
two
programming
languages
defined
,
we
can
turn
to
the
compiler
definition
.
*
)
(
**
**
Translation
*
)
...
...
@@ -163,7 +168,7 @@ Eval simpl in compile (Binop Plus (Const 2) (Const 2)).
Eval
simpl
in
compile
(
Binop
Times
(
Binop
Plus
(
Const
2
)
(
Const
2
))
(
Const
7
))
.
(
**
[
=
iConst
7
::
iConst
2
::
iConst
2
::
iBinop
Plus
::
iBinop
Times
::
nil
:
prog
]
*
)
(
**
We
can
also
run
our
compiled
programs
and
check
that
they
give
the
right
results
.
*
)
(
**
%
\
smallskip
{}%
We
can
also
run
our
compiled
programs
and
check
that
they
give
the
right
results
.
*
)
Eval
simpl
in
progDenote
(
compile
(
Const
42
))
nil
.
(
**
[
=
Some
(
42
::
nil
)
:
option
stack
]
*
)
...
...
@@ -615,10 +620,12 @@ Eval simpl in texpDenote (TBinop TLt (TBinop TPlus (TNConst 2) (TNConst 2))
(
TNConst
7
))
.
(
**
[
=
true
:
typeDenote
Bool
]
*
)
(
**
%
\
smallskip
{}%
Now
we
are
ready
to
define
a
suitable
stack
machine
target
for
compilation
.
*
)
(
**
**
Target
Language
*
)
(
**
Now
we
want
to
define
a
suitable
stack
machine
target
for
compilation
.
In
the
example
of
the
untyped
language
,
stack
machine
programs
could
encounter
stack
underflows
and
"get stuck."
This
was
unfortunate
,
since
we
had
to
deal
with
this
complication
even
though
we
proved
that
our
compiler
never
produced
underflowing
programs
.
We
could
have
used
dependent
types
to
force
all
stack
machine
programs
to
be
underflow
-
free
.
(
**
In
the
example
of
the
untyped
language
,
stack
machine
programs
could
encounter
stack
underflows
and
"get stuck."
This
was
unfortunate
,
since
we
had
to
deal
with
this
complication
even
though
we
proved
that
our
compiler
never
produced
underflowing
programs
.
We
could
have
used
dependent
types
to
force
all
stack
machine
programs
to
be
underflow
-
free
.
For
our
new
languages
,
besides
underflow
,
we
also
have
the
problem
of
stack
slots
with
naturals
instead
of
bools
or
vice
versa
.
This
time
,
we
will
use
indexed
typed
families
to
avoid
the
need
to
reason
about
potential
failures
.
...
...
@@ -761,6 +768,8 @@ Eval simpl in tprogDenote (tcompile (TBinop TLt (TBinop TPlus (TNConst 2) (TNCon
(
TNConst
7
))
nil
)
tt
.
(
**
[
=
(
true
,
tt
)
:
vstack
(
Bool
::
nil
)]
*
)
(
**
%
\
smallskip
{}%
The
compiler
seems
to
be
working
,
so
let
us
turn
to
proving
that
it
_
always_
works
.
*
)
(
**
**
Translation
Correctness
*
)
...
...
src/Subset.v
View file @
77382d81
...
...
@@ -85,7 +85,7 @@ Eval compute in pred_strong1 two_gt0.
:
nat
]]
%
\
smallskip
{}%
One
aspect
in
particular
of
the
definition
of
[
pred_strong1
]
may
be
surprising
.
We
took
advantage
of
[
Definition
]
'
s
syntactic
sugar
for
defining
function
arguments
in
the
case
of
[
n
]
,
but
we
bound
the
proofs
later
with
explicit
[
fun
]
expressions
.
Let
us
see
what
happens
if
we
write
this
function
in
the
way
that
at
first
seems
most
natural
.
One
aspect
in
particular
of
the
definition
of
[
pred_strong1
]
may
be
surprising
.
We
took
advantage
of
[
Definition
]
'
s
syntactic
sugar
for
defining
function
arguments
in
the
case
of
[
n
]
,
but
we
bound
the
proofs
later
with
explicit
[
fun
]
expressions
.
Let
us
see
what
happens
if
we
write
this
function
in
the
way
that
at
first
seems
most
natural
.
%
\
vspace
{-
.15
in
}%
[[
Definition
pred_strong1
'
(
n
:
nat
)
(
pf
:
n
>
0
)
:
nat
:=
...
...
@@ -153,7 +153,7 @@ Inductive sig (A : Type) (P : A -> Prop) : Type :=
exist
:
forall
x
:
A
,
P
x
->
sig
P
]]
%
\
smallskip
{}%
The
family
[
sig
]
is
a
Curry
-
Howard
twin
of
[
ex
]
,
except
that
[
sig
]
is
in
[
Type
]
,
while
[
ex
]
is
in
[
Prop
]
.
That
means
that
[
sig
]
values
can
survive
extraction
,
while
[
ex
]
proofs
will
always
be
erased
.
The
actual
details
of
extraction
of
[
sig
]
s
are
more
subtle
,
as
we
will
see
shortly
.
The
family
[
sig
]
is
a
Curry
-
Howard
twin
of
[
ex
]
,
except
that
[
sig
]
is
in
[
Type
]
,
while
[
ex
]
is
in
[
Prop
]
.
That
means
that
[
sig
]
values
can
survive
extraction
,
while
[
ex
]
proofs
will
always
be
erased
.
The
actual
details
of
extraction
of
[
sig
]
s
are
more
subtle
,
as
we
will
see
shortly
.
We
rewrite
[
pred_strong1
]
,
using
some
syntactic
sugar
for
subset
types
.
*
)
...
...
@@ -301,7 +301,7 @@ end
:
forall
n
:
nat
,
n
>
0
->
{
m
:
nat
|
n
=
S
m
}
]]
%
\
smallskip
{}%
We
see
the
code
we
entered
,
with
some
proofs
filled
in
.
The
first
proof
obligation
,
the
second
argument
to
[
False_rec
]
,
is
filled
in
with
a
nasty
-
looking
proof
term
that
we
can
be
glad
we
did
not
enter
by
hand
.
The
second
proof
obligation
is
a
simple
reflexivity
proof
.
*
)
We
see
the
code
we
entered
,
with
some
proofs
filled
in
.
The
first
proof
obligation
,
the
second
argument
to
[
False_rec
]
,
is
filled
in
with
a
nasty
-
looking
proof
term
that
we
can
be
glad
we
did
not
enter
by
hand
.
The
second
proof
obligation
is
a
simple
reflexivity
proof
.
*
)
Eval
compute
in
pred_strong4
two_gt0
.
(
**
%
\
vspace
{-
.15
in
}%
[[
...
...
@@ -309,7 +309,7 @@ Eval compute in pred_strong4 two_gt0.
:
{
m
:
nat
|
2
=
S
m
}
]]
%
\
smallskip
{}%
A
tactic
modifier
called
%
\
index
{
tactics
!
abstract
}%
[
abstract
]
can
be
helpful
for
producing
shorter
terms
,
by
automatically
abstracting
subgoals
into
named
lemmas
.
*
)
A
tactic
modifier
called
%
\
index
{
tactics
!
abstract
}%
[
abstract
]
can
be
helpful
for
producing
shorter
terms
,
by
automatically
abstracting
subgoals
into
named
lemmas
.
*
)
(
*
begin
thide
*
)
Definition
pred_strong4
'
:
forall
n
:
nat
,
n
>
0
->
{
m
:
nat
|
n
=
S
m
}.
...
...
@@ -358,7 +358,7 @@ Eval compute in pred_strong5 two_gt0.
:
{
m
:
nat
|
2
=
S
m
}
]]
%
\
smallskip
{}%
One
other
alternative
is
worth
demonstrating
.
Recent
Coq
versions
include
a
facility
called
%
\
index
{
Program
}%
[
Program
]
that
streamlines
this
style
of
definition
.
Here
is
a
complete
implementation
using
[
Program
]
.%
\
index
{
Vernacular
commands
!
Obligation
Tactic
}
\
index
{
Vernacular
commands
!
Program
Definition
}%
*
)
One
other
alternative
is
worth
demonstrating
.
Recent
Coq
versions
include
a
facility
called
%
\
index
{
Program
}%
[
Program
]
that
streamlines
this
style
of
definition
.
Here
is
a
complete
implementation
using
[
Program
]
.%
\
index
{
Vernacular
commands
!
Obligation
Tactic
}
\
index
{
Vernacular
commands
!
Program
Definition
}%
*
)
Obligation
Tactic
:=
crush
.
...
...
@@ -376,7 +376,7 @@ Eval compute in pred_strong6 two_gt0.
:
{
m
:
nat
|
2
=
S
m
}
]]
%
\
smallskip
{}%
In
this
case
,
we
see
that
the
new
definition
yields
the
same
computational
behavior
as
before
.
*
)
In
this
case
,
we
see
that
the
new
definition
yields
the
same
computational
behavior
as
before
.
*
)
(
**
*
Decidable
Proposition
Types
*
)
...
...
@@ -421,7 +421,7 @@ Eval compute in eq_nat_dec 2 3.
:
{
2
=
3
}
+
{
2
<>
3
}
]]
%
\
smallskip
{}%
Note
that
the
%
\
coqdocnotation
{%
#
<
tt
>
#
Yes
#
</
tt
>
#
%}%
and
%
\
coqdocnotation
{%
#
<
tt
>
#
No
#
</
tt
>
#
%}%
notations
are
hiding
proofs
establishing
the
correctness
of
the
outputs
.
Note
that
the
%
\
coqdocnotation
{%
#
<
tt
>
#
Yes
#
</
tt
>
#
%}%
and
%
\
coqdocnotation
{%
#
<
tt
>
#
No
#
</
tt
>
#
%}%
notations
are
hiding
proofs
establishing
the
correctness
of
the
outputs
.
Our
definition
extracts
to
reasonable
OCaml
code
.
*
)
...
...
@@ -529,7 +529,7 @@ Eval compute in In_dec eq_nat_dec 3 (1 :: 2 :: nil).
:
{
In
3
(
1
::
2
::
nil
)
}
+
{~
In
3
(
1
::
2
::
nil
)
}
]]
%
\
smallskip
{}%
[
In_dec
]
has
a
reasonable
extraction
to
OCaml
.
*
)
[
In_dec
]
has
a
reasonable
extraction
to
OCaml
.
*
)
Extraction
In_dec
.
(
*
end
thide
*
)
...
...
@@ -596,7 +596,7 @@ Eval compute in pred_strong7 0.
:
{{
m
|
0
=
S
m
}}
]]
%
\
smallskip
{}%
Because
we
used
[
maybe
]
,
one
valid
implementation
of
the
type
we
gave
[
pred_strong7
]
would
return
[
??
]
in
every
case
.
We
can
strengthen
the
type
to
rule
out
such
vacuous
implementations
,
and
the
type
family
%
\
index
{
Gallina
terms
!
sumor
}%
[
sumor
]
from
the
standard
library
provides
the
easiest
starting
point
.
For
type
[
A
]
and
proposition
[
B
]
,
[
A
+
{
B
}
]
desugars
to
[
sumor
A
B
]
,
whose
values
are
either
values
of
[
A
]
or
proofs
of
[
B
]
.
*
)
Because
we
used
[
maybe
]
,
one
valid
implementation
of
the
type
we
gave
[
pred_strong7
]
would
return
[
??
]
in
every
case
.
We
can
strengthen
the
type
to
rule
out
such
vacuous
implementations
,
and
the
type
family
%
\
index
{
Gallina
terms
!
sumor
}%
[
sumor
]
from
the
standard
library
provides
the
easiest
starting
point
.
For
type
[
A
]
and
proposition
[
B
]
,
[
A
+
{
B
}
]
desugars
to
[
sumor
A
B
]
,
whose
values
are
either
values
of
[
A
]
or
proofs
of
[
B
]
.
*
)
Print
sumor
.
(
**
%
\
vspace
{-
.15
in
}%
[[
...
...
@@ -604,7 +604,7 @@ Inductive sumor (A : Type) (B : Prop) : Type :=
inleft
:
A
->
A
+
{
B
}
|
inright
:
B
->
A
+
{
B
}
]]
%
\
smallskip
{}%
We
add
notations
for
easy
use
of
the
[
sumor
]
constructors
.
The
second
notation
is
specialized
to
[
sumor
]
s
whose
[
A
]
parameters
are
instantiated
with
regular
subset
types
,
since
this
is
how
we
will
use
[
sumor
]
below
.
*
)
We
add
notations
for
easy
use
of
the
[
sumor
]
constructors
.
The
second
notation
is
specialized
to
[
sumor
]
s
whose
[
A
]
parameters
are
instantiated
with
regular
subset
types
,
since
this
is
how
we
will
use
[
sumor
]
below
.
*
)
Notation
"!!"
:=
(
inright
_
_
)
.
Notation
"[|| x ||]"
:=
(
inleft
_
[
x
])
.
...
...
@@ -776,7 +776,7 @@ Eval simpl in typeCheck (Plus (Nat 1) (Bool false)).
:
{{
t
|
hasType
(
Plus
(
Nat
1
)
(
Bool
false
))
t
}}
]]
%
\
smallskip
{}%
The
type
checker
also
extracts
to
some
reasonable
OCaml
code
.
*
)
The
type
checker
also
extracts
to
some
reasonable
OCaml
code
.
*
)
Extraction
typeCheck
.
...
...
@@ -929,4 +929,4 @@ Eval simpl in typeCheck' (Plus (Nat 1) (Bool false)).
{
(
forall
t
:
type
,
~
hasType
(
Plus
(
Nat
1
)
(
Bool
false
))
t
)
}
]]
%
\
smallskip
{}%
The
results
of
simplifying
calls
to
[
typeCheck
'
]
look
deceptively
similar
to
the
results
for
[
typeCheck
]
,
but
now
the
types
of
the
results
provide
more
information
.
*
)
The
results
of
simplifying
calls
to
[
typeCheck
'
]
look
deceptively
similar
to
the
results
for
[
typeCheck
]
,
but
now
the
types
of
the
results
provide
more
information
.
*
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment