coq


Folding back after unfolding


I have fold_length defined like this:
Inductive list (X: Type) : Type :=
| nil : list X
| cons : X -> list X -> list X.
Arguments nil {X}.
Arguments cons {X} _ _.
Notation "x :: y" := (cons x y)
(at level 60, right associativity).
Notation "[ ]" := nil.
Fixpoint fold {X Y:Type} (f: X -> Y -> Y) (l:list X) (b:Y) : Y :=
match l with
| nil => b
| h :: t => f h (fold f t b)
end.
Definition fold_length {X : Type} (l : list X) : nat :=
fold (fun _ n => S n) l 0.
I have to prove a theorem and this is my code so far:
Theorem fold_length_correct : forall X (l : list X),
fold_length l = length l.
Proof.
intros X l.
induction l as [| n l' IHl'].
- simpl.
unfold fold_length.
simpl.
reflexivity.
- simpl.
unfold fold_length.
simpl.
Right now, my goal looks like this:
X : Type
n : X
l' : list X
IHl' : fold_length l' = length l'
============================
S (fold (fun (_ : X) (n0 : nat) => S n0) l' 0) = S (length l')
Now I want to convert the expression (fold (fun (_ : X) (n0 : nat) => S n0) l' 0) to fold_length l' using the definition of fold_length. Is there a way to do that in Coq (There seems to something named fold tactic in Coq. Can that achieve this.) ?
Also, is there a way to prove the above theorem without the usage of unfold and fold tactic ?
To answer your first question, yes, the fold tactic can be used here to replace the left side of the equality with S (fold_length l'). Usually, for a function f, fold f is not powerful enough to detect what it can fold. But if you specify the whole term, like here fold (fold_length l'), it works.
Regarding your second question, note that tactics like reflexivity or assumption can conclude if the terms involved are equal up to some simplifications. Here, the base case of the induction can be just reflexivity. For the second case, assuming that fold is List.fold_right, simpl can surprisingly simplify without unfolding and you should not need unfold or fold here either.

Related Links

Dependent type list concatenation in Coq
How to access the elements of a record in coq
Type hierarchy definition in Coq or Agda
Applying tactics to local subgoals of a semicolon chain in Coq
How to build an inductive type for cobordisms using Coq?
Coq: “dependent induction” inside Ltac
Omitting forall in Coq
Why can't inversion be used on a universally qualified hypothesis in Coq?
How to duplicate a hypothesis in Coq?
Why Coq doesn't allow inversion, destruct, etc. when the goal is a Type?
Working with semirings in Coq
Eliminating cases with propositions in Coq
Using sets as hyphotesis and goal in COQ
What does `omega` really do here?
What is the idiomatic way to express countable infinity in Coq?
Coq dependent types

Categories

HOME
image
hive
appx
include
setup-deployment
programming-languages
yahoo-oauth
razor
analysis
rubygems
autotools
basic
medical
windows-10-universal
vifm
vault
mapserver
correlation
php-7.1
flask-wtforms
iron-router
dynamics-crm-online
caml
ef-migrations
serilog
errorlevel
icloud-api
dxf
underflow
wtx
webkitspeechrecognition
unboundid
yadcf
xquery-3.0
semantic-versioning
gtrendsr
environment-modules
devextreme
swift3.0.2
sqlite2
unobtrusive-validation
sql-server-agent
dynamic-reports
glew
unixodbc
node-sass
.net-4.6.2
user-accounts
jlink
tactic
composite-key
media-player
windows-iot-core-10
titanium-android
smart-table
url-pattern
bonobo
file-writing
measures
merge-conflict-resolution
simplewebrtc
blackberry-10
make-install
livequery
photobucket
tcpserver
cartesian-product
ora-00900
sdhc
wyam
map-projections
sysinternals
sankey-diagram
javax.mail
cdt
neolane
mesa
eol
browser-detection
dice
datawindow
chrono
php-parser
mod-auth
f#-powerpack
preference
castle-monorail
compiler-specific
boost-smart-ptr
defensive-programming
ugc
.net-1.0

Resources

Database Users
RDBMS discuss
Database Dev&Adm
javascript
java
csharp
php
android
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App