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
ff18c64f
Commit
ff18c64f
authored
Mar 26, 2012
by
Adam Chlipala
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prose for second LogicProg section
parent
4567a287
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
80 additions
and
0 deletions
+80
-0
LogicProg.v
src/LogicProg.v
+80
-0
No files found.
src/LogicProg.v
View file @
ff18c64f
...
@@ -436,13 +436,31 @@ Qed.
...
@@ -436,13 +436,31 @@ Qed.
(
**
*
Searching
for
Underconstrained
Values
*
)
(
**
*
Searching
for
Underconstrained
Values
*
)
(
**
Recall
the
definition
of
the
list
length
function
.
*
)
Print
length
.
Print
length
.
(
**
%
\
vspace
{-
.15
in
}%
[[
length
=
fun
A
:
Type
=>
fix
length
(
l
:
list
A
)
:
nat
:=
match
l
with
|
nil
=>
0
|
_
::
l
'
=>
S
(
length
l
'
)
end
]]
This
function
is
easy
to
reason
about
in
the
forward
direction
,
computing
output
from
input
.
*
)
Example
length_1_2
:
length
(
1
::
2
::
nil
)
=
2.
Example
length_1_2
:
length
(
1
::
2
::
nil
)
=
2.
auto
.
auto
.
Qed
.
Qed
.
Print
length_1_2
.
Print
length_1_2
.
(
**
%
\
vspace
{-
.15
in
}%
[[
length_1_2
=
eq_refl
]]
As
in
the
last
section
,
we
will
prove
some
lemmas
to
recast
[
length
]
in
logic
programming
style
,
to
help
us
compute
inputs
from
outputs
.
*
)
(
*
begin
thide
*
)
(
*
begin
thide
*
)
Theorem
length_O
:
forall
A
,
length
(
nil
(
A
:=
A
))
=
O
.
Theorem
length_O
:
forall
A
,
length
(
nil
(
A
:=
A
))
=
O
.
...
@@ -458,15 +476,43 @@ Qed.
...
@@ -458,15 +476,43 @@ Qed.
Hint
Resolve
length_O
length_S
.
Hint
Resolve
length_O
length_S
.
(
*
end
thide
*
)
(
*
end
thide
*
)
(
**
Let
us
apply
these
hints
to
prove
that
a
[
list
nat
]
of
length
2
exists
.
*
)
Example
length_is_2
:
exists
ls
:
list
nat
,
length
ls
=
2.
Example
length_is_2
:
exists
ls
:
list
nat
,
length
ls
=
2.
(
*
begin
thide
*
)
(
*
begin
thide
*
)
eauto
.
eauto
.
(
**
<<
No
more
subgoals
but
non
-
instantiated
existential
variables
:
Existential
1
=
?
20249
:
[
|-
nat
]
Existential
2
=
?
20252
:
[
|-
nat
]
>>
Coq
complains
that
we
finished
the
proof
without
determining
the
values
of
some
unification
variables
created
during
proof
search
.
The
error
message
may
seem
a
bit
silly
,
since
%
\
emph
{%
#
<
i
>
#
any
#
</
i
>
#
%}%
value
of
type
[
nat
]
(
for
instance
,
0
)
can
be
plugged
in
for
either
variable
!
However
,
for
more
complex
types
,
finding
their
inhabitants
may
be
as
complex
as
theorem
-
proving
in
general
.
The
%
\
index
{
Vernacular
commands
!
Show
Proof
}%
[
Show
Proof
]
command
shows
exactly
which
proof
term
[
eauto
]
has
found
,
with
the
undetermined
unification
variables
appearing
explicitly
where
they
are
used
.
*
)
Show
Proof
.
Show
Proof
.
(
**
<<
Proof:
ex_intro
(
fun
ls
:
list
nat
=>
length
ls
=
2
)
(
?
20249
::
?
20252
::
nil
)
(
length_S
?
20249
(
?
20252
::
nil
)
(
length_S
?
20252
nil
(
length_O
nat
)))
>>
%
\
vspace
{-
.2
in
}%
*
)
Abort
.
Abort
.
(
*
end
thide
*
)
(
*
end
thide
*
)
(
**
We
see
that
the
two
unification
variables
stand
for
the
two
elements
of
the
list
.
Indeed
,
list
length
is
independent
of
data
values
.
Paradoxically
,
we
can
make
the
proof
search
process
easier
by
constraining
the
list
further
,
so
that
proof
search
naturally
locates
appropriate
data
elements
by
unification
.
The
library
predicate
[
Forall
]
will
be
helpful
.
*
)
Print
Forall
.
Print
Forall
.
(
**
%
\
vspace
{-
.15
in
}%
[[
Inductive
Forall
(
A
:
Type
)
(
P
:
A
->
Prop
)
:
list
A
->
Prop
:=
Forall_nil
:
Forall
P
nil
|
Forall_cons
:
forall
(
x
:
A
)
(
l
:
list
A
)
,
P
x
->
Forall
P
l
->
Forall
P
(
x
::
l
)
]]
*
)
Example
length_is_2
:
exists
ls
:
list
nat
,
length
ls
=
2
Example
length_is_2
:
exists
ls
:
list
nat
,
length
ls
=
2
/
\
Forall
(
fun
n
=>
n
>=
1
)
ls
.
/
\
Forall
(
fun
n
=>
n
>=
1
)
ls
.
...
@@ -475,8 +521,26 @@ Example length_is_2 : exists ls : list nat, length ls = 2
...
@@ -475,8 +521,26 @@ Example length_is_2 : exists ls : list nat, length ls = 2
Qed
.
Qed
.
(
*
end
thide
*
)
(
*
end
thide
*
)
(
**
We
can
see
which
list
[
eauto
]
found
by
printing
the
proof
term
.
*
)
Print
length_is_2
.
(
**
%
\
vspace
{-
.15
in
}%
[[
length_is_2
=
ex_intro
(
fun
ls
:
list
nat
=>
length
ls
=
2
/
\
Forall
(
fun
n
:
nat
=>
n
>=
1
)
ls
)
(
1
::
1
::
nil
)
(
conj
(
length_S
1
(
1
::
nil
)
(
length_S
1
nil
(
length_O
nat
)))
(
Forall_cons
1
(
le_n
1
)
(
Forall_cons
1
(
le_n
1
)
(
Forall_nil
(
fun
n
:
nat
=>
n
>=
1
)))))
]]
*
)
(
**
Let
us
try
one
more
,
fancier
example
.
First
,
we
use
a
standard
high
-
order
function
to
define
a
function
for
summing
all
data
elements
of
a
list
.
*
)
Definition
sum
:=
fold_right
plus
O
.
Definition
sum
:=
fold_right
plus
O
.
(
**
Another
basic
lemma
will
be
helpful
to
guide
proof
search
.
*
)
(
*
begin
thide
*
)
(
*
begin
thide
*
)
Lemma
plusO
'
:
forall
n
m
,
Lemma
plusO
'
:
forall
n
m
,
n
=
m
n
=
m
...
@@ -486,9 +550,13 @@ Qed.
...
@@ -486,9 +550,13 @@ Qed.
Hint
Resolve
plusO
'
.
Hint
Resolve
plusO
'
.
(
**
Finally
,
we
meet
%
\
index
{
Vernacular
commands
!
Hint
Extern
}%
[
Hint
Extern
]
,
the
command
to
register
a
custom
hint
.
That
is
,
we
provide
a
pattern
to
match
against
goals
during
proof
search
.
Whenever
the
pattern
matches
,
a
tactic
(
given
to
the
right
of
an
arrow
[
=>
])
is
attempted
.
Below
,
the
number
[
1
]
gives
a
priority
for
this
step
.
Lower
priorities
are
tried
before
higher
priorities
,
which
can
have
a
significant
effect
on
proof
search
time
.
*
)
Hint
Extern
1
(
sum
_
=
_
)
=>
simpl
.
Hint
Extern
1
(
sum
_
=
_
)
=>
simpl
.
(
*
end
thide
*
)
(
*
end
thide
*
)
(
**
Now
we
can
find
a
length
-
2
list
whose
sum
is
0.
*
)
Example
length_and_sum
:
exists
ls
:
list
nat
,
length
ls
=
2
Example
length_and_sum
:
exists
ls
:
list
nat
,
length
ls
=
2
/
\
sum
ls
=
O
.
/
\
sum
ls
=
O
.
(
*
begin
thide
*
)
(
*
begin
thide
*
)
...
@@ -496,7 +564,11 @@ Example length_and_sum : exists ls : list nat, length ls = 2
...
@@ -496,7 +564,11 @@ Example length_and_sum : exists ls : list nat, length ls = 2
Qed
.
Qed
.
(
*
end
thide
*
)
(
*
end
thide
*
)
(
*
begin
hide
*
)
Print
length_and_sum
.
Print
length_and_sum
.
(
*
end
hide
*
)
(
**
Printing
the
proof
term
shows
the
unsurprising
list
that
is
found
.
Here
is
an
example
where
it
is
less
obvious
which
list
will
be
used
.
Can
you
guess
which
list
[
eauto
]
will
choose
?
*
)
Example
length_and_sum
'
:
exists
ls
:
list
nat
,
length
ls
=
5
Example
length_and_sum
'
:
exists
ls
:
list
nat
,
length
ls
=
5
/
\
sum
ls
=
42.
/
\
sum
ls
=
42.
...
@@ -505,7 +577,11 @@ Example length_and_sum' : exists ls : list nat, length ls = 5
...
@@ -505,7 +577,11 @@ Example length_and_sum' : exists ls : list nat, length ls = 5
Qed
.
Qed
.
(
*
end
thide
*
)
(
*
end
thide
*
)
(
*
begin
hide
*
)
Print
length_and_sum
'
.
Print
length_and_sum
'
.
(
*
end
hide
*
)
(
**
We
will
give
away
part
of
the
answer
and
say
that
the
above
list
is
less
interesting
than
we
would
like
,
because
it
contains
too
many
zeroes
.
A
further
constraint
forces
a
different
solution
for
a
smaller
instance
of
the
problem
.
*
)
Example
length_and_sum
''
:
exists
ls
:
list
nat
,
length
ls
=
2
Example
length_and_sum
''
:
exists
ls
:
list
nat
,
length
ls
=
2
/
\
sum
ls
=
3
/
\
sum
ls
=
3
...
@@ -515,7 +591,11 @@ Example length_and_sum'' : exists ls : list nat, length ls = 2
...
@@ -515,7 +591,11 @@ Example length_and_sum'' : exists ls : list nat, length ls = 2
Qed
.
Qed
.
(
*
end
thide
*
)
(
*
end
thide
*
)
(
*
begin
hide
*
)
Print
length_and_sum
''
.
Print
length_and_sum
''
.
(
*
end
hide
*
)
(
**
We
could
continue
through
exercises
of
this
kind
,
but
even
more
interesting
than
finding
lists
automatically
is
finding
%
\
emph
{%
#
<
i
>
#
programs
#
</
i
>
#
%}%
automatically
.
*
)
(
**
*
Synthesizing
Programs
*
)
(
**
*
Synthesizing
Programs
*
)
...
...
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