Skip to content

Commit 9f86ba6

Browse files
authored
feat: self-contained Makefile (#30)
1 parent b8fef29 commit 9f86ba6

12 files changed

+255
-50
lines changed

.docker/Dockerfile

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# This Dockerfile mostly exists to verify that the Makefile works;
2+
# it's unlikely that we'll actually use it "in production"!
3+
# You may also need to allow the Docker engine a lot of memory (32gb?)
4+
FROM ubuntu
5+
6+
USER root
7+
8+
# Set timezone to UTC to avoid prompts from tzdata.
9+
RUN TZ=UTC ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
10+
# Install prerequisites.
11+
RUN apt-get update && \
12+
apt-get install -y git libgmp-dev cmake ccache gcc-10 g++-10 && \
13+
apt-get install -y build-essential && \
14+
apt-get install -y curl python3-yaml python3 python-is-python3 && \
15+
apt-get clean
16+
17+
# create a non-root user
18+
RUN useradd -m lean
19+
20+
USER lean
21+
WORKDIR /home/lean
22+
23+
SHELL ["/bin/bash", "-c"]
24+
# set the entrypoint to be a login shell, so everything is on the PATH
25+
ENTRYPOINT ["/bin/bash", "-l"]
26+
27+
# make sure binaries are available even in non-login shells
28+
ENV PATH="/home/lean/.elan/bin:/home/lean/.local/bin:$PATH"
29+
30+
## TODO: Once `lake` is distributed as part of Lean4, hopefully we can just install `elan`:
31+
# install elan
32+
# RUN curl https://raw.githubusercontent.com/Kha/elan/master/elan-init.sh -sSf | sh -s -- -y && \
33+
# . ~/.profile && \
34+
# elan toolchain uninstall stable
35+
36+
## For now, we need to grab an old version of `elan-init` and build `lake` ourselves:
37+
38+
RUN curl -L https://github.com/leanprover/elan/releases/download/v1.0.8/elan-x86_64-unknown-linux-gnu.tar.gz -o elan.tar.gz && \
39+
tar zxf elan.tar.gz && \
40+
rm elan.tar.gz && \
41+
./elan-init -y && \
42+
. ~/.profile && \
43+
elan toolchain uninstall stable
44+
45+
# We need to set CC and CCX while building lake.
46+
ENV CC="gcc-10"
47+
ENV CXX="g++-10"
48+
49+
RUN mkdir -p /home/lean/.local/bin
50+
RUN git clone https://github.com/leanprover/lake && \
51+
cd lake && \
52+
./build.sh && \
53+
ln -s /home/lean/lake/build/bin/lake /home/lean/.local/bin/lake
54+
55+
# TODO: switch back to the main mathport repository once the Makefile PR merges.
56+
RUN git clone https://github.com/semorrison/mathport --branch Makefile
57+
WORKDIR /home/lean/mathport
58+
59+
# We need to set CC and CCX while building lean3 / lean4.
60+
ENV CC="gcc-10"
61+
ENV CXX="g++-10"
62+
63+
RUN make mathbin-source
64+
RUN make lean3-source
65+
RUN make lean4-source
66+
RUN make lean3-predata
67+
RUN make mathbin-predata
68+
RUN make build
69+
RUN make port-lean
70+
RUN make port-mathbin

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ build/
44
Logs/
55
PreData/
66
Lib4/*/
7+
lean_packages/
8+
sources/

Makefile

+95-44
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,95 @@
1+
### Makefile for mathport
2+
3+
# This is not a "real" makefile, i.e. it does not detect dependencies between targets.
4+
5+
## Targets:
6+
# `lean4-source`: clone `lean4`, patch `kernel/inductive.cpp`, compile, and `elan override`
7+
# `mathbin-source`: clone mathlib3, and create `all.lean`
8+
# `lean3-source`: clone lean3, and create `all.lean` (run after `mathbin-source`, to get the right commit)
9+
# `lean3-predata`: create `.ast` and `.tlean` files from Lean3
10+
# `mathbin-predata`: create `.ast` and `.tlean` files from mathlib3
11+
# `build`: compile mathport
12+
# `port-lean`: run mathport on Lean3
13+
# `port-mathbin`: run mathport on mathlib3
14+
15+
## Prerequisites:
16+
# curl, git, cmake, elan, python3
17+
18+
# We make the following assumptions about versions:
19+
#
20+
# * `lean-toolchain` points to the same version of `lean4` as
21+
# the branch/commit of `mathlib4` selected in `lakefile.lean`.
22+
#
23+
# It will automatically identify the version of `lean3` than `mathlib` currently uses.
24+
125
all:
226

327
unport:
428
rm -rf Lib4 Logs/*
529
git checkout HEAD -- Lib4
630

31+
# Select which commit of mathlib3 to use.
32+
MATHBIN_COMMIT=master
33+
34+
# Unfortunately we can't use vanilla lean4: we need to cherrypick
35+
# https://github.com/dselsam/lean4/commit/9228d3949bda8c1411e707b3e20650fa1fdb9b4d
36+
lean4-source:
37+
rm -rf sources/lean4
38+
mkdir -p sources
39+
cd sources && git clone --depth 1 --branch `cat ../lean-toolchain | sed "s/.*://"` https://github.com/leanprover/lean4-nightly/ lean4
40+
cd sources/lean4 && git submodule update --init src/lake
41+
cd sources/lean4 && patch -u src/kernel/inductive.cpp < ../../whnf-type-inductives.patch
42+
cd sources/lean4 && rm -rf build && mkdir -p build/release && cd build/release && \
43+
cmake ../.. && make -j`python -c 'import multiprocessing as mp; print(mp.cpu_count())'`
44+
elan toolchain link lean4-mathport-cherrypick sources/lean4/build/release/stage1/
45+
elan override set lean4-mathport-cherrypick
46+
47+
# Obtain the requested commit from `mathlib`, and create `all.lean`
48+
mathbin-source:
49+
mkdir -p sources
50+
if [ ! -d "sources/mathlib" ]; then \
51+
cd sources && git clone https://github.com/leanprover-community/mathlib.git; \
52+
fi
53+
cd sources/mathlib && git clean -xfd && git checkout $(MATHBIN_COMMIT)
54+
cd sources/mathlib && leanpkg configure && ./scripts/mk_all.sh
55+
56+
# Obtain the commit from (community edition) Lean 3 which mathlib is using, and create `all.lean`.
57+
lean3-source:
58+
mkdir -p sources
59+
if [ ! -d "sources/lean" ]; then \
60+
cd sources && git clone https://github.com/leanprover-community/lean.git; \
61+
fi
62+
cd sources/lean && git clean -xfd && git checkout `cd ../mathlib && lean --version | sed -e "s/.*commit \([0-9a-f]*\).*/\1/"`
63+
mkdir -p sources/lean/build/release
64+
# Run cmake, to create `version.lean` from `version.lean.in`.
65+
cd sources/lean/build/release && cmake ../../src
66+
# Create `all.lean`.
67+
./mk_all.sh sources/lean/library/
68+
69+
# Build .ast and .tlean files for Lean 3
70+
lean3-predata: lean3-source
71+
mkdir -p PreData
72+
rm -rf PreData/Leanbin
73+
find sources/lean/library -name "*.olean" -delete # ast only exported when oleans not present
74+
# FIXME replace `stable` here with what mathlib is using?
75+
cd sources/lean && elan override set stable
76+
cd sources/lean && lean --make --recursive --ast --tlean library
77+
cp -r sources/lean/library PreData/Leanbin
78+
find PreData/ -name "*.lean" -delete
79+
find PreData/ -name "*.olean" -delete
80+
81+
# Build .ast and .tlean files for Mathlib 3.
82+
mathbin-predata: mathbin-source
83+
rm -rf PreData/Mathbin
84+
find sources/mathlib -name "*.olean" -delete # ast only exported when oleans not present
85+
# By changing into the directory, `elan` automatically dispatches to the correct binary.
86+
cd sources/mathlib && lean --make --recursive --ast --tlean src
87+
cp -r sources/mathlib PreData/Mathbin
88+
find PreData/ -name "*.lean" -delete
89+
find PreData/ -name "*.olean" -delete
90+
91+
predata: lean3-predata mathbin-predata
92+
793
init-logs:
894
mkdir -p Logs
995

@@ -12,57 +98,22 @@ MATHPORT_LIB=./build/lib
1298

1399
LEANBIN_LIB=./Lib4/leanbin/build/lib
14100
MATHBIN_LIB=./Lib4/mathbin/build/lib
15-
LIQUIDBIN_LIB=./Lib4/liquidbin/build/lib
16101

17-
port-lean: init-logs
18-
LEAN_PATH=$(MATHPORT_LIB):$(MATHLIB4_LIB):$(LEANBIN_LIB) time ./build/bin/mathport config.json Leanbin::all >> Logs/mathport.out 2> Logs/mathport.err
102+
build:
103+
lake build
104+
105+
port-lean: init-logs build
106+
LEAN_PATH=$(MATHPORT_LIB):$(MATHLIB4_LIB):$(LEANBIN_LIB) ./build/bin/mathport config.json Leanbin::all >> Logs/mathport.out 2> Logs/mathport.err
19107
LEAN_PATH=$(MATHPORT_LIB):$(MATHLIB4_LIB):$(LEANBIN_LIB) lean --o=$(LEANBIN_LIB)/Leanbin.olean ./Lib4/leanbin/Leanbin.lean
20108
cp lean-toolchain Lib4/leanbin
21109

22-
port-mathlib: port-lean
23-
LEAN_PATH=$(MATHPORT_LIB):$(MATHLIB4_LIB):$(LEANBIN_LIB):$(MATHBIN_LIB) time ./build/bin/mathport config.json Leanbin::all Mathbin::all >> Logs/mathport.out 2> Logs/mathport.err
110+
port-mathbin: port-lean
111+
LEAN_PATH=$(MATHPORT_LIB):$(MATHLIB4_LIB):$(LEANBIN_LIB):$(MATHBIN_LIB) ./build/bin/mathport config.json Leanbin::all Mathbin::all >> Logs/mathport.out 2> Logs/mathport.err
24112
LEAN_PATH=$(MATHPORT_LIB):$(MATHLIB4_LIB):$(LEANBIN_LIB):$(MATHBIN_LIB) lean --o=$(MATHBIN_LIB)/Mathbin.olean ./Lib4/mathbin/Mathbin.lean
25113
cp lean-toolchain Lib4/mathbin
26114

27-
port-liquid: port-mathlib
28-
LEAN_PATH=$(MATHPORT_LIB):$(MATHLIB4_LIB):$(LEANBIN_LIB):$(MATHBIN_LIB):$(LIQUIDBIN_LIB) time ./build/bin/mathport config.json Leanbin::all Mathbin::all Liquidbin::all >> Logs/mathport.out 2> Logs/mathport.err
29-
LEAN_PATH=$(MATHPORT_LIB):$(MATHLIB4_LIB):$(LEANBIN_LIB):$(MATHBIN_LIB):$(LIQUIDBIN_LIB) lean --o=$(LIQUIDBIN_LIB)/Liquidbin.olean ./Lib4/liquidbin/Liquidbin.lean
30-
cp lean-toolchain Lib4/liquidbin
115+
test:
116+
LEAN_PATH=$(MATHPORT_LIB):$(MATHLIB4_LIB):$(LEANBIN_LIB):$(MATHBIN_LIB) lean ./Test.lean
31117

32118
tar-lib4:
33119
tar --exclude 'lean_packages' -czvf mathport-release.tar.gz Lib4 Logs PreData
34-
35-
lean3-predata:
36-
mkdir -p PreData
37-
rm -rf PreData/Leanbin
38-
find $(LEAN3_LIB) -name "*.olean" -delete # ast only exported when oleans not present
39-
LEAN_PATH=$(LEAN3_LIB) $(LEAN3_BIN)/lean --make --recursive --ast --tlean $(LEAN3_LIB)
40-
LEAN_PATH=$(LEAN3_LIB):$(LEAN3_PKG) $(LEAN3_BIN)/lean --make --recursive --ast --tlean $(LEAN3_PKG)
41-
cp -r $(LEAN3_LIB) PreData/Leanbin
42-
find PreData/ -name "*.lean" -delete
43-
find PreData/ -name "*.olean" -delete
44-
45-
mathbin-predata: lean3-predata
46-
rm -rf PreData/Mathbin
47-
find $(MATHLIB3_SRC) -name "*.olean" -delete # ast only exported when oleans not present
48-
LEAN_PATH=$(LEAN3_LIB):$(MATHLIB3_SRC) $(LEAN3_BIN)/lean --make --recursive --ast $(MATHLIB3_SRC)
49-
LEAN_PATH=$(LEAN3_LIB):$(MATHLIB3_SRC) $(LEAN3_BIN)/lean --make --recursive --tlean $(MATHLIB3_SRC)
50-
cp -r $(MATHLIB3_SRC) PreData/Mathbin
51-
find PreData/ -name "*.lean" -delete
52-
find PreData/ -name "*.olean" -delete
53-
54-
liquid-predata: mathbin-predata
55-
rm -rf PreData/Liquid
56-
find $(LIQUID3_SRC) -name "*.olean" -delete # ast only exported when oleans not present
57-
LEAN_PATH=$(LEAN3_LIB):$(MATHLIB3_SRC):$(LIQUID3_SRC) $(LEAN3_BIN)/lean --make --recursive --ast --tlean $(LIQUID3_SRC)
58-
cp -r $(LIQUID3_SRC) PreData/Liquidbin
59-
find PreData/ -name "*.lean" -delete
60-
find PreData/ -name "*.olean" -delete
61-
62-
tmp-liquid-predata:
63-
rm -rf PreData/Liquid
64-
find $(LIQUID3_SRC) -name "*.olean" -delete # ast only exported when oleans not present
65-
LEAN_PATH=$(LEAN3_LIB):$(MATHLIB3_SRC):$(LIQUID3_SRC) $(LEAN3_BIN)/lean --make --recursive --ast --tlean $(LIQUID3_SRC)
66-
cp -r $(LIQUID3_SRC) PreData/Liquidbin
67-
find PreData/ -name "*.lean" -delete
68-
find PreData/ -name "*.olean" -delete

Mathport/Prelude/Syntax.lean

-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ syntax (name := async) "async " tacticSeq : tactic
217217

218218
namespace Conv
219219

220-
syntax (name := first) "first " withPosition((group(colGe "|" convSeq))+) : conv
221220
macro "try " t:convSeq : conv => `(first | $t | skip)
222221
syntax "runConv " doSeq : conv
223222

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ Mathport is a tool for porting Lean3 projects to Lean4. It consists of two (loos
44

55
- "binport", which translates Lean3 `.lean` files to Lean4 `.olean` files
66
- "synport", which best-effort translates Lean3 `.lean` files to Lean4 `.lean` files
7+
8+
See the `Makefile` for usage (it takes several hours to rebuild the mathlib port),
9+
or the `test-mathport` repository if you'd prefer to use a pre-built artifact.

Test.lean

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Mathlib
2+
import Mathbin
3+
4+
#check Semiring
5+
#lookup3 semiring
6+
#check Semiringₓ
7+
8+
#lookup3 nat.exists_infinite_primes
9+
10+
example (n : Nat) : n + n = 2 * n := by ring

config.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
"outRoot": "Lib4",
44
"packages": {
55
"Leanbin": "PreData/Leanbin",
6-
"Mathbin": "PreData/Mathbin",
7-
"Liquidbin": "PreData/Liquidbin"
6+
"Mathbin": "PreData/Mathbin/src"
87
}
98
},
109
"stringsToKeep": [

lakefile.lean

+10-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,17 @@ open Lake DSL System
55
package mathport {
66
dependencies := #[{
77
name := "mathlib",
8-
src := Source.git "https://github.com/dselsam/mathlib4.git" "lake" none,
8+
-- We point to a particular commit in mathlib4,
9+
-- as changes to tactics in mathlib4 often cause breakages here,
10+
-- particularly in `Mathport/Syntax/Translate/Tactic/Mathlib.lean`.
11+
-- We'll need to keep updating that file, and bumping the commit here.
12+
src := Source.git "https://github.com/leanprover-community/mathlib4.git" "b28a3d51e722d8b43367035e0eb5790b4cb6da53",
913
dir := FilePath.mk "."
1014
}],
1115
binRoot := `MathportApp
12-
linkArgs := #["-rdynamic"]
16+
moreLinkArgs :=
17+
if Platform.isWindows then
18+
#["-Wl,--export-all"]
19+
else
20+
#["-rdynamic"]
1321
}

lean-toolchain

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
leanprover/lean4:nightly-2021-10-02
1+
leanprover/lean4:nightly-2021-10-16

mathlib

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit c33b823e24ba6307f7a2cdaf1cead76a7029a14d

mk_all.sh

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
# Usage: mk_all.sh [subdirectory]
3+
#
4+
5+
cd $1
6+
find . -name \*.lean -not -name all.lean \
7+
| sed 's,^\./,,;s,\.lean$,,;s,/,.,g;s,^,import ,' \
8+
| sort > ./all.lean

whnf-type-inductives.patch

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
From 9228d3949bda8c1411e707b3e20650fa1fdb9b4d Mon Sep 17 00:00:00 2001
2+
From: Daniel Selsam <[email protected]>
3+
Date: Sat, 23 Jan 2021 15:00:09 -0800
4+
Subject: [PATCH] temp: whnf the type of inductives
5+
6+
---
7+
src/kernel/inductive.cpp | 8 +++++++-
8+
1 file changed, 7 insertions(+), 1 deletion(-)
9+
10+
diff --git a/src/kernel/inductive.cpp b/src/kernel/inductive.cpp
11+
index 3d1a47659b..9c48383c36 100644
12+
--- a/src/kernel/inductive.cpp
13+
+++ b/src/kernel/inductive.cpp
14+
@@ -168,6 +168,7 @@ public:
15+
tc().check(type, m_lparams);
16+
m_nindices.push_back(0);
17+
unsigned i = 0;
18+
+ type = whnf(type);
19+
while (is_pi(type)) {
20+
if (i < m_nparams) {
21+
if (first) {
22+
@@ -181,9 +182,11 @@ public:
23+
}
24+
i++;
25+
} else {
26+
- type = binding_body(type);
27+
+ expr index = mk_local_decl_for(type);
28+
+ type = instantiate(binding_body(type), index);
29+
m_nindices.back()++;
30+
}
31+
+ type = whnf(type);
32+
}
33+
if (i != m_nparams)
34+
throw kernel_exception(m_env, "number of parameters mismatch in inductive datatype declaration");
35+
@@ -527,6 +530,8 @@ public:
36+
rec_info info;
37+
expr t = ind_type.get_type();
38+
unsigned i = 0;
39+
+
40+
+ t = whnf(t);
41+
while (is_pi(t)) {
42+
if (i < m_nparams) {
43+
t = instantiate(binding_body(t), m_params[i]);
44+
@@ -536,6 +541,7 @@ public:
45+
t = instantiate(binding_body(t), idx);
46+
}
47+
i++;
48+
+ t = whnf(t);
49+
}
50+
info.m_major = mk_local_decl("t", mk_app(mk_app(m_ind_cnsts[d_idx], m_params), info.m_indices));
51+
expr C_ty = mk_sort(m_elim_level);
52+
--
53+
2.30.1 (Apple Git-130)
54+

0 commit comments

Comments
 (0)