Switch to Hakyll as the build system for PLFA (#540)
This commit is contained in:
parent
ea8bee4461
commit
2c82ce21da
509 changed files with 103793 additions and 1327 deletions
|
@ -9,7 +9,3 @@ else
|
|||
echo "Checking for whitespace violations..."
|
||||
fix-whitespace --check
|
||||
fi
|
||||
|
||||
# Run the test suite.
|
||||
echo "Running the test suite..."
|
||||
make test-offline
|
||||
|
|
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -3,6 +3,13 @@
|
|||
.agda-stdlib.sed
|
||||
.links-*.sed
|
||||
|
||||
## Haskell files
|
||||
_site/
|
||||
_cache/
|
||||
stack.yaml.lock
|
||||
.stack-work/
|
||||
dist-newstyle
|
||||
|
||||
## Jekyll files
|
||||
_site/
|
||||
.sass-cache/
|
||||
|
@ -26,4 +33,5 @@ auto/
|
|||
|
||||
## Misc build files
|
||||
out/
|
||||
.versions/
|
||||
*.zip
|
||||
versions/plfa.github.io-web-*/
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "standard-library"]
|
||||
path = standard-library
|
||||
url = git@github.com:agda/agda-stdlib.git
|
24
404.html
Executable file
24
404.html
Executable file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
.container {
|
||||
margin: 10px auto;
|
||||
max-width: 600px;
|
||||
text-align: center;
|
||||
}
|
||||
h1 {
|
||||
margin: 30px 0;
|
||||
font-size: 4em;
|
||||
line-height: 1;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container">
|
||||
<h1>404</h1>
|
||||
|
||||
<p><strong>Page not found :(</strong></p>
|
||||
<p>The requested page could not be found.</p>
|
||||
</div>
|
17
Gemfile
17
Gemfile
|
@ -1,19 +1,8 @@
|
|||
# NOTE: the Gemfile is no longer used by the main distribution of PLFA,
|
||||
# but is still used to build legacy versions 19.07 and 20.08.
|
||||
|
||||
source "https://rubygems.org"
|
||||
|
||||
group :jekyll_plugins do
|
||||
gem 'github-pages'
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'guard'
|
||||
gem 'guard-shell'
|
||||
gem 'html-proofer'
|
||||
# ffi-1.13.1 is broken on macos
|
||||
# https://github.com/ffi/ffi/issues/791
|
||||
gem 'ffi', '~> 1.12.2'
|
||||
end
|
||||
|
||||
group :epub do
|
||||
gem 'safe_yaml'
|
||||
gem 'liquid'
|
||||
end
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
require 'fileutils'
|
||||
|
||||
guard :shell do
|
||||
watch(%r{^(.+)\.lagda\.md$}) do |m|
|
||||
src = m[0]
|
||||
out = "#{File.dirname(src).sub('src','out')}/#{File.basename(src,'.lagda.md')}.md"
|
||||
`make #{out}` unless File.basename(src).start_with?('.#')
|
||||
end
|
||||
end
|
429
Makefile
429
Makefile
|
@ -1,273 +1,202 @@
|
|||
SHELL := /usr/bin/env bash
|
||||
AGDA_FILES := $(shell find . -type f -and \( -path './src/*' -or -path './courses/*' \) -and -name '*.lagda.md')
|
||||
AGDAI_FILES := $(shell find . -type f -and \( -path './src/*' -or -path './courses/*' \) -and -name '*.agdai')
|
||||
MARKDOWN_FILES := $(subst courses/,out/,$(subst src/,out/,$(subst .lagda.md,.md,$(AGDA_FILES))))
|
||||
PLFA_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
PANDOC := pandoc
|
||||
EPUBCHECK := epubcheck
|
||||
RUBY := ruby
|
||||
GEM := $(RUBY) -S gem
|
||||
BUNDLE := $(RUBY) -S bundle
|
||||
JEKYLL := $(BUNDLE) exec jekyll
|
||||
HTMLPROOFER := $(BUNDLE) exec htmlproofer
|
||||
LUA_FILES := $(shell find . -type f -and -path '*/epub/*' -and -name '*.lua')
|
||||
RELEASE_VERSIONS := 19.08 20.07
|
||||
RELEASES := $(addsuffix /,$(RELEASE_VERSIONS))
|
||||
LATEST_VERSION := $(word $(words $(RELEASE_VERSIONS)),$(RELEASE_VERSIONS))
|
||||
#################################################################################
|
||||
# Configuration
|
||||
#################################################################################
|
||||
|
||||
ifeq ($(AGDA_STDLIB_VERSION),)
|
||||
AGDA_STDLIB_URL := https://agda.github.io/agda-stdlib/
|
||||
else
|
||||
AGDA_STDLIB_URL := https://agda.github.io/agda-stdlib/v$(AGDA_STDLIB_VERSION)/
|
||||
SITE_DIR := _site
|
||||
CACHE_DIR := _cache
|
||||
TMP_DIR := $(CACHE_DIR)/tmp
|
||||
|
||||
|
||||
#################################################################################
|
||||
# Setup Git Hooks
|
||||
#################################################################################
|
||||
|
||||
.PHONY: init
|
||||
init: setup-check-fix-whitespace setup-check-htmlproofer
|
||||
git config core.hooksPath .githooks
|
||||
|
||||
|
||||
#################################################################################
|
||||
# Build PLFA site
|
||||
#################################################################################
|
||||
|
||||
.PHONY: build
|
||||
build: $(SITE_DIR)
|
||||
|
||||
$(SITE_DIR): authors contributors css courses hs posts public src templates
|
||||
stack build && stack exec site build
|
||||
|
||||
|
||||
#################################################################################
|
||||
# Test generated site with HTMLProofer
|
||||
#################################################################################
|
||||
|
||||
.PHONY: test
|
||||
test: setup-install-htmlproofer $(SITE_DIR)
|
||||
cd $(SITE_DIR) && htmlproofer \
|
||||
--check-html \
|
||||
--disable-external \
|
||||
--report-invalid-tags \
|
||||
--report-missing-names \
|
||||
--report-script-embeds \
|
||||
--report-missing-doctype \
|
||||
--report-eof-tags \
|
||||
--report-mismatched-tags \
|
||||
--check-img-http \
|
||||
--check-opengraph \
|
||||
.
|
||||
|
||||
#################################################################################
|
||||
# Test generated EPUB with EPUBCheck
|
||||
#################################################################################
|
||||
|
||||
.PHONY: test-epub
|
||||
test-epub: setup-check-epubcheck $(SITE_DIR)/plfa.epub
|
||||
epubcheck $(SITE_DIR)/plfa.epub
|
||||
|
||||
|
||||
#################################################################################
|
||||
# Automatically rebuild the site on changes, and start a preview server
|
||||
#################################################################################
|
||||
|
||||
.PHONY: watch
|
||||
watch:
|
||||
stack build && stack exec site watch
|
||||
|
||||
|
||||
#################################################################################
|
||||
# Update contributor metadata in `contributors/`
|
||||
#################################################################################
|
||||
|
||||
.PHONY: update-contributors
|
||||
update-contributors:
|
||||
stack build && stack exec update-contributors
|
||||
|
||||
|
||||
#################################################################################
|
||||
# Clean up and remove the cache
|
||||
#################################################################################
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
stack build && stack exec site clean
|
||||
|
||||
|
||||
#################################################################################
|
||||
# List targets in Makefile
|
||||
#################################################################################
|
||||
|
||||
.PHONY: list
|
||||
list:
|
||||
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
|
||||
|
||||
|
||||
#################################################################################
|
||||
# Setup dependencies
|
||||
#################################################################################
|
||||
|
||||
.PHONY: setup-check-stack
|
||||
setup-check-stack:
|
||||
ifeq (,$(wildcard $(shell which stack)))
|
||||
@echo "The command you called requires the Haskell Tool Stack"
|
||||
@echo "See: https://docs.haskellstack.org/en/stable/install_and_upgrade/"
|
||||
@exit 1
|
||||
endif
|
||||
|
||||
.PHONY: setup-check-npm
|
||||
setup-check-npm:
|
||||
ifeq (,$(wildcard $(shell which npm)))
|
||||
@echo "The command you called requires the Node Package Manager"
|
||||
@echo "See: https://www.npmjs.com/get-npm"
|
||||
@exit 1
|
||||
endif
|
||||
|
||||
.PHONY: setup-check-gem
|
||||
setup-check-gem:
|
||||
ifeq (,$(wildcard $(shell which gem)))
|
||||
@echo "The command you called requires the RubyGems Package Manager"
|
||||
@echo "See: https://www.ruby-lang.org/en/documentation/installation/"
|
||||
@exit 1
|
||||
endif
|
||||
|
||||
.PHONY: setup-check-fix-whitespace
|
||||
setup-check-fix-whitespace: setup-check-stack
|
||||
ifeq (,$(wildcard $(shell which fix-whitespace)))
|
||||
@echo "The command you called requires fix-whitespace"
|
||||
@echo "Run: git clone https://github.com/agda/fix-whitespace"
|
||||
@echo " cd fix-whitespace/"
|
||||
@echo " stack install --stack-yaml stack-8.8.3.yaml"
|
||||
endif
|
||||
|
||||
.PHONY: setup-check-epubcheck
|
||||
setup-check-epubcheck:
|
||||
ifeq (,$(wildcard $(shell which epubcheck)))
|
||||
@echo "The command you called requires EPUBCheck"
|
||||
@echo "See: https://github.com/w3c/epubcheck"
|
||||
endif
|
||||
|
||||
.PHONY: setup-install-htmlproofer
|
||||
setup-install-htmlproofer: setup-check-gem
|
||||
ifeq (,$(wildcard $(shell which htmlproofer)))
|
||||
@echo "Installing HTMLProofer..."
|
||||
gem install html-proofer
|
||||
endif
|
||||
|
||||
.PHONY: setup-install-bundler
|
||||
setup-install-bundler: setup-check-gem
|
||||
ifeq (,$(wildcard $(shell which bundle)))
|
||||
@echo "Installing Ruby Bundler..."
|
||||
gem install bundle
|
||||
endif
|
||||
|
||||
|
||||
#################################################################################
|
||||
# Build legacy versions of website using Jekyll
|
||||
#################################################################################
|
||||
|
||||
LEGACY_VERSIONS := 19.08 20.07
|
||||
LEGACY_VERSION_DIRS := $(addprefix versions/,$(addsuffix /,$(LEGACY_VERSIONS)))
|
||||
|
||||
legacy-versions: setup-install-bundle $(LEGACY_VERSION_DIRS)
|
||||
|
||||
ifeq ($(shell sed --version >/dev/null 2>&1; echo $$?),1)
|
||||
SEDI := sed -i ""
|
||||
else
|
||||
SEDI := sed -i
|
||||
endif
|
||||
|
||||
|
||||
# Configure the repository to use .githooks
|
||||
init:
|
||||
git config core.hooksPath .githooks
|
||||
|
||||
|
||||
# Build PLFA web version and test links
|
||||
default: test
|
||||
|
||||
|
||||
# Start Jekyll server with --incremental
|
||||
serve:
|
||||
$(JEKYLL) serve --incremental
|
||||
|
||||
# Start detached Jekyll server
|
||||
server-start:
|
||||
$(JEKYLL) serve --no-watch --detach
|
||||
|
||||
# Stop detached Jekyll server
|
||||
server-stop:
|
||||
pkill -f jekyll
|
||||
|
||||
.phony: serve server-start server-stop
|
||||
|
||||
|
||||
# Build PLFA web version using Jekyll
|
||||
build: $(MARKDOWN_FILES)
|
||||
$(JEKYLL) build
|
||||
|
||||
# Build PLFA web version using Jekyll with --incremental
|
||||
build-incremental: $(MARKDOWN_FILES)
|
||||
$(JEKYLL) build --incremental
|
||||
|
||||
# Download PLFA web releases
|
||||
build-history: latest/ $(RELEASES)
|
||||
|
||||
latest/: $(addprefix .versions/plfa.github.io-web-,$(addsuffix /,$(LATEST_VERSION)))
|
||||
cd $< \
|
||||
&& $(JEKYLL) clean \
|
||||
&& $(JEKYLL) build --destination '../../latest' --baseurl '/latest'
|
||||
|
||||
# Download PLFA web release and build it under the relevant folder
|
||||
define build_release
|
||||
define build_legacy_version
|
||||
version := $(1)
|
||||
out := $(addsuffix /,$(1))
|
||||
url := $(addprefix https://github.com/plfa/plfa.github.io/archive/web-,$(addsuffix .zip,$(1)))
|
||||
tmp_zip := $(addprefix .versions/plfa.github.io-web-,$(addsuffix .zip,$(1)))
|
||||
tmp_dir := $(addprefix .versions/plfa.github.io-web-,$(addsuffix /,$(1)))
|
||||
tmp_zip := $(addprefix versions/plfa.github.io-web-,$(addsuffix .zip,$(1)))
|
||||
tmp_dir := $(addprefix versions/plfa.github.io-web-,$(addsuffix /,$(1)))
|
||||
baseurl := $(addprefix /,$(1))
|
||||
|
||||
$$(tmp_zip): tmp_zip = $(addprefix .versions/plfa.github.io-web-,$(addsuffix .zip,$(1)))
|
||||
$$(tmp_zip): tmp_zip = $(addprefix versions/plfa.github.io-web-,$(addsuffix .zip,$(1)))
|
||||
$$(tmp_zip): url = $(addprefix https://github.com/plfa/plfa.github.io/archive/web-,$(addsuffix .zip,$(1)))
|
||||
$$(tmp_zip):
|
||||
@mkdir -p .versions/
|
||||
wget -c $$(url) -O $$(tmp_zip)
|
||||
@mkdir -p versions/
|
||||
@wget -c $$(url) -O $$(tmp_zip)
|
||||
|
||||
$$(tmp_dir): version = $(1)
|
||||
$$(tmp_dir): tmp_dir = $(addprefix .versions/plfa.github.io-web-,$(addsuffix /,$(1)))
|
||||
$$(tmp_dir): tmp_zip = $(addprefix .versions/plfa.github.io-web-,$(addsuffix .zip,$(1)))
|
||||
$$(tmp_dir): tmp_dir = $(addprefix versions/plfa.github.io-web-,$(addsuffix /,$(1)))
|
||||
$$(tmp_dir): tmp_zip = $(addprefix versions/plfa.github.io-web-,$(addsuffix .zip,$(1)))
|
||||
$$(tmp_dir): $$(tmp_zip)
|
||||
yes | unzip -qq $$(tmp_zip) -d .versions/
|
||||
$(SEDI) "s/branch: dev/branch: dev-$$(version)/" $$(addsuffix _config.yml,$$(tmp_dir))
|
||||
@yes | unzip -qq $$(tmp_zip) -d versions/
|
||||
@$(SEDI) "s/branch: dev/branch: dev-$$(version)/" $$(addsuffix _config.yml,$$(tmp_dir))
|
||||
|
||||
$$(out): out = $(addsuffix /,$(1))
|
||||
$$(out): url = $(addprefix https://github.com/plfa/plfa.github.io/archive/web-,$(addsuffix .zip,$(1)))
|
||||
$$(out): tmp_dir = $(addprefix .versions/plfa.github.io-web-,$(addsuffix /,$(1)))
|
||||
$$(out): baseurl = $(addprefix /,$(1))
|
||||
$$(out): $$(tmp_dir)
|
||||
cd $$(tmp_dir) \
|
||||
versions/$$(out): out = $(addsuffix /,$(1))
|
||||
versions/$$(out): url = $(addprefix https://github.com/plfa/plfa.github.io/archive/web-,$(addsuffix .zip,$(1)))
|
||||
versions/$$(out): tmp_dir = $(addprefix versions/plfa.github.io-web-,$(addsuffix /,$(1)))
|
||||
versions/$$(out): baseurl = $(addprefix /,$(1))
|
||||
versions/$$(out): $$(tmp_dir)
|
||||
@echo "source \"https://rubygems.org\"\n\ngroup :jekyll_plugins do\n gem 'github-pages'\nend" > $$(tmp_dir)/Gemfile
|
||||
@cd $$(tmp_dir) \
|
||||
&& rm -rf _posts \
|
||||
&& $(JEKYLL) clean \
|
||||
&& $(JEKYLL) build --destination '../../$$(out)' --baseurl '$$(baseurl)'
|
||||
&& bundle install \
|
||||
&& bundle exec jekyll clean \
|
||||
&& bundle exec jekyll build --destination '../$$(out)' --baseurl '$$(baseurl)'
|
||||
endef
|
||||
|
||||
# Incorporate previous releases of PLFA web version
|
||||
$(foreach release_version,$(RELEASE_VERSIONS),$(eval $(call build_release,$(release_version))))
|
||||
|
||||
# Convert literal Agda to Markdown using highlight.sh
|
||||
define AGDA_template
|
||||
in := $(1)
|
||||
out := $(subst courses/,out/,$(subst src/,out/,$(subst .lagda.md,.md,$(1))))
|
||||
$$(out) : in = $(1)
|
||||
$$(out) : out = $(subst courses/,out/,$(subst src/,out/,$(subst .lagda.md,.md,$(1))))
|
||||
$$(out) : $$(in)
|
||||
@echo "Processing $$(subst ./,,$$(in))"
|
||||
@mkdir -p out/
|
||||
ifeq (,$$(findstring courses/,$$(in)))
|
||||
./highlight.sh $$(subst ./,,$$(in)) --include-path=src/
|
||||
else
|
||||
# Fix links to the file itself (out/<filename> to out/<filepath>)
|
||||
./highlight.sh $$(subst ./,,$$(in)) --include-path=src/ --include-path=$$(subst ./,,$$(dir $$(in)))
|
||||
endif
|
||||
endef
|
||||
|
||||
$(foreach agda,$(AGDA_FILES),$(eval $(call AGDA_template,$(agda))))
|
||||
|
||||
.phony: build build-incremental
|
||||
|
||||
|
||||
# Test links using htmlproofer
|
||||
test: build
|
||||
$(HTMLPROOFER) '_site'
|
||||
|
||||
# Test local links using htmlproofer
|
||||
test-offline: build
|
||||
$(HTMLPROOFER) '_site' --disable-external
|
||||
|
||||
# Test local links for stability under different base URLs
|
||||
test-stable-offline: $(MARKDOWN_FILES)
|
||||
$(JEKYLL) clean
|
||||
$(JEKYLL) build --destination '_site/stable' --baseurl '/stable'
|
||||
$(HTMLPROOFER) '_site' --disable-external
|
||||
|
||||
.phony: test test-offline test-stable-offline
|
||||
|
||||
|
||||
# Build EPUB using Pandoc
|
||||
epub: out/epub/plfa.epub
|
||||
|
||||
# Test EPUB using EPUBCheck
|
||||
epubcheck: out/epub/plfa.epub
|
||||
$(EPUBCHECK) out/epub/plfa.epub
|
||||
|
||||
out/epub/plfa.epub: $(AGDA_FILES) $(LUA_FILES) epub/main.css out/epub/acknowledgements.md
|
||||
@mkdir -p out/epub/
|
||||
$(PANDOC) --strip-comments \
|
||||
--css=epub/main.css \
|
||||
--epub-embed-font='assets/fonts/mononoki.woff' \
|
||||
--epub-embed-font='assets/fonts/FreeMono.woff' \
|
||||
--epub-embed-font='assets/fonts/DejaVuSansMono.woff' \
|
||||
--lua-filter epub/include-files.lua \
|
||||
--lua-filter epub/rewrite-links.lua \
|
||||
--lua-filter epub/rewrite-html-ul.lua \
|
||||
--lua-filter epub/default-code-class.lua -M default-code-class=agda \
|
||||
--standalone \
|
||||
--fail-if-warnings \
|
||||
--toc --toc-depth=2 \
|
||||
--epub-chapter-level=2 \
|
||||
-o "$@" \
|
||||
epub/index.md
|
||||
|
||||
out/epub/acknowledgements.md: src/plfa/acknowledgements.md _config.yml
|
||||
@mkdir -p out/epub/
|
||||
$(BUNDLE) exec ruby epub/render-liquid-template.rb _config.yml $< $@
|
||||
|
||||
.phony: epub epubcheck
|
||||
|
||||
|
||||
# Clean auxiliary files
|
||||
clean:
|
||||
rm -f .agda-stdlib.sed .links-*.sed out/epub/acknowledgements.md
|
||||
rm -rf .versions
|
||||
ifneq ($(strip $(AGDAI_FILES)),)
|
||||
rm $(AGDAI_FILES)
|
||||
endif
|
||||
|
||||
# Clean generated files
|
||||
clobber: clean
|
||||
$(JEKYLL) clean
|
||||
rm -rf out/
|
||||
rm -rf latest/ $(RELEASES)
|
||||
|
||||
.phony: clean clobber
|
||||
|
||||
|
||||
# Setup Travis
|
||||
travis-setup:\
|
||||
travis-install-agda\
|
||||
travis-install-agda-stdlib\
|
||||
travis-install-acknowledgements
|
||||
|
||||
.phony: travis-setup
|
||||
|
||||
|
||||
# Setup Agda
|
||||
|
||||
travis-install-agda:\
|
||||
$(HOME)/.local/bin/agda\
|
||||
$(HOME)/.agda/defaults\
|
||||
$(HOME)/.agda/libraries
|
||||
|
||||
$(HOME)/.agda/defaults:
|
||||
echo "standard-library" >> $(HOME)/.agda/defaults
|
||||
echo "plfa" >> $(HOME)/.agda/defaults
|
||||
|
||||
$(HOME)/.agda/libraries:
|
||||
echo "$(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION)/standard-library.agda-lib" >> $(HOME)/.agda/libraries
|
||||
echo "$(PLFA_DIR)/plfa.agda-lib" >> $(HOME)/.agda/libraries
|
||||
|
||||
$(HOME)/.local/bin/agda:
|
||||
curl -L https://github.com/agda/agda/archive/v$(AGDA_VERSION).zip\
|
||||
-o $(HOME)/agda-$(AGDA_VERSION).zip
|
||||
unzip -qq $(HOME)/agda-$(AGDA_VERSION).zip -d $(HOME)
|
||||
cd $(HOME)/agda-$(AGDA_VERSION);\
|
||||
stack install --stack-yaml=stack-$(GHC_VERSION).yaml
|
||||
|
||||
travis-uninstall-agda:
|
||||
rm -rf $(HOME)/agda-$(AGDA_VERSION)/
|
||||
rm -f $(HOME)/.local/bin/agda
|
||||
rm -f $(HOME)/.local/bin/agda-mode
|
||||
|
||||
travis-reinstall-agda: travis-uninstall-agda travis-install-agda
|
||||
|
||||
.phony: travis-install-agda travis-uninstall-agda travis-reinstall-agda
|
||||
|
||||
|
||||
# Setup Agda Standard Library
|
||||
|
||||
travis-install-agda-stdlib: $(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION)/src
|
||||
|
||||
$(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION)/src:
|
||||
curl -L https://github.com/agda/agda-stdlib/archive/v$(AGDA_STDLIB_VERSION).zip\
|
||||
-o $(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION).zip
|
||||
unzip -qq $(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION).zip -d $(HOME)
|
||||
mkdir -p $(HOME)/.agda
|
||||
|
||||
travis-uninstall-agda-stdlib:
|
||||
rm $(HOME)/.agda/defaults
|
||||
rm $(HOME)/.agda/libraries
|
||||
rm -rf $(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION)/
|
||||
|
||||
travis-reinstall-agda-stdlib: travis-uninstall-agda-stdlib travis-install-agda-stdlib
|
||||
|
||||
.phony: travis-install-agda-stdlib travis-uninstall-agda-stdlib travis-reinstall-agda-stdlib epub
|
||||
|
||||
|
||||
# Setup Acknowledgements
|
||||
|
||||
travis-install-acknowledgements: $(HOME)/.local/bin/acknowledgements
|
||||
|
||||
$(HOME)/.local/bin/acknowledgements:
|
||||
curl -L https://github.com/plfa/acknowledgements/archive/master.zip\
|
||||
-o $(HOME)/acknowledgements-master.zip
|
||||
unzip -qq $(HOME)/acknowledgements-master.zip -d $(HOME)
|
||||
cd $(HOME)/acknowledgements-master;\
|
||||
stack install
|
||||
|
||||
travis-uninstall-acknowledgements:
|
||||
rm -rf $(HOME)/acknowledgements-master/
|
||||
rm $(HOME)/.local/bin/acknowledgements
|
||||
|
||||
travis-reinstall-acknowledgements: travis-uninstall-acknowledgements travis-reinstall-acknowledgements
|
||||
|
||||
.phony: travis-install-acknowledgements travis-uninstall-acknowledgements travis-reinstall-acknowledgements
|
||||
$(foreach legacy_version,$(LEGACY_VERSIONS),$(eval $(call build_legacy_version,$(legacy_version))))
|
||||
|
|
359
README.md
359
README.md
|
@ -1,10 +1,13 @@
|
|||
---
|
||||
layout : page
|
||||
title : Getting Started
|
||||
prev : /Preface/
|
||||
permalink : /GettingStarted/
|
||||
next : /Naturals/
|
||||
---
|
||||
|
||||
<!-- Status & Version Badges -->
|
||||
|
||||
[![Calendar Version][plfa-calver]][plfa-latest]
|
||||
[![Build Status][plfa-status]][plfa-travis]
|
||||
[![Agda][agda-version]][agda]
|
||||
|
@ -12,19 +15,46 @@ permalink: /GettingStarted/
|
|||
|
||||
|
||||
## Dependencies for users
|
||||
You can read PLFA [online][plfa] without installing anything. However, if you wish to interact with the code or complete the exercises, you need several things:
|
||||
|
||||
You can read PLFA [online][plfa] without installing anything.
|
||||
However, if you wish to interact with the code or complete the exercises, you need several things:
|
||||
|
||||
- [Agda][agda]
|
||||
- [Agda standard library][agda-stdlib]
|
||||
- [PLFA][plfa-dev]
|
||||
- [Stack](#install-the-haskell-tool-stack)
|
||||
- [Git](#install-git)
|
||||
- [Agda](#install-agda-using-stack)
|
||||
- [Agda standard library](#install-plfa-and-the-agda-standard-library)
|
||||
- [PLFA](#install-plfa-and-the-agda-standard-library)
|
||||
|
||||
PLFA is tested against specific versions of Agda and the standard library, which are shown in the badges above. Agda and the standard library change rapidly, and these changes often break PLFA, so using older or newer versions usually causes problems.
|
||||
|
||||
### Installing Agda using Stack
|
||||
There are several versions of Agda and its standard library online. If you are using a package manager, like Homebrew or Debian apt, the version of Agda available there may be out-of date. Furthermore, Agda is under active development, so if you install the development version from the GitHub, you might find the developers have introduced changes which break the code here. Therefore, it’s important to have the specific versions of Agda and the standard library shown above.
|
||||
|
||||
The easiest way to install any specific version of Agda is using [Stack][haskell-stack]. You can get the required version of Agda from GitHub, either by cloning the repository and switching to the correct branch, or by downloading [the zip archive][agda]:
|
||||
|
||||
### On macOS: Install the XCode Command Line Tools
|
||||
On macOS, you’ll need to install the [XCode Command Line Tools][xcode]. For most versions of macOS, you can install these by running the following command:
|
||||
```bash
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
### Install the Haskell Tool Stack
|
||||
Agda is written in Haskell, so to install it we’ll need the *Haskell Tool Stack*, or *Stack* for short. Stack is a program for managing different Haskell compilers and packages:
|
||||
|
||||
- *On UNIX and macOS.* Your package manager has a package for Stack, that’s probably your easiest option. For instance, Homebrew on macOS and APT on Debian offer the “haskell-stack” package. Otherwise, you can follow the instructions on [the Stack website][haskell-stack]. Usually, Stack installs binaries at “~/.local/bin”. Please ensure this is on your PATH, by including the following in your shell configuration, e.g., in `~/.bash_profile`:
|
||||
```bash
|
||||
export PATH="${HOME}/.local/bin:${PATH}"
|
||||
```
|
||||
Finally, ensure that you’ve got the latest version of Stack, by running:
|
||||
```bash
|
||||
stack upgrade
|
||||
```
|
||||
|
||||
- *On Windows.* There is a Windows installer on [the Stack website][haskell-stack].
|
||||
|
||||
|
||||
### Install Git
|
||||
If you do not already have Git installed, see [the Git downloads page][git].
|
||||
|
||||
|
||||
### Install Agda using Stack
|
||||
The easiest way to install a *specific version* of Agda is using [Stack][haskell-stack]. You can get the required version of Agda from GitHub, either by cloning the repository and switching to the correct branch, or by downloading [the zip archive][agda]:
|
||||
```bash
|
||||
git clone https://github.com/agda/agda.git
|
||||
cd agda
|
||||
|
@ -34,38 +64,140 @@ To install Agda, run Stack from the Agda source directory:
|
|||
```bash
|
||||
stack install --stack-yaml stack-8.8.3.yaml
|
||||
```
|
||||
If you want Stack to use you system installation of GHC, you can pass the `--system-ghc` flag and select the appropriate `stack-*.yaml` file. For instance, if you have GHC 8.2.2 installed, run:
|
||||
*This step will take a long time and a lot of memory to complete.*
|
||||
|
||||
#### Using an existing installation of GHC
|
||||
Stack is perfectly capable of installing and managing versions of the [Glasgow Haskell Compiler][haskell-ghc] for you. However, if you already have a copy of GHC installed, and you want Stack to use your system installation, you can pass the `--system-ghc` flag and select the appropriate “stack-*.yaml” file. For instance, if you have GHC 8.2.2 installed, run:
|
||||
```bash
|
||||
stack install --system-ghc --stack-yaml stack-8.2.2.yaml
|
||||
```
|
||||
|
||||
### Installing the Standard Library and PLFA
|
||||
#### Check if Agda was installed correctly
|
||||
If you’d like, you can test to see if you’ve installed Agda correctly. Create a file called “hello.agda” with these lines:
|
||||
```agda
|
||||
data Greeting : Set where
|
||||
hello : Greeting
|
||||
|
||||
You can get the required version of the Agda standard library from GitHub, either by cloning the repository and switching to the correct branch, or by downloading [the zip archive][agda-stdlib]:
|
||||
greet : Greeting
|
||||
greet = hello
|
||||
```
|
||||
From a command line, change to the same directory where your “hello.agda” file is located. Then run:
|
||||
```bash
|
||||
git clone https://github.com/agda/agda-stdlib.git
|
||||
agda -v 2 hello.agda
|
||||
```
|
||||
You should see a short message like the following, but no errors:
|
||||
```
|
||||
Checking hello (/path/to/hello.agda).
|
||||
Finished hello.
|
||||
```
|
||||
|
||||
|
||||
### Install PLFA and the Agda standard library
|
||||
You can get the latest version of Programming Language Foundations in Agda from GitHub, either by cloning the repository, or by downloading [the zip archive][plfa-dev]:
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/plfa/plfa.github.io plfa
|
||||
```
|
||||
PLFA ships with the required version of the Agda standard library, so if you cloned with the `--recurse-submodules` flag, you’ve already got, in the “standard-library” directory!
|
||||
|
||||
If you forgot to add the `--recurse-submodules` flag, no worries, we can fix that!
|
||||
```bash
|
||||
cd plfa/
|
||||
git submodule update --recursive
|
||||
```
|
||||
If you obtained PLFA by downloading the zip archive, you can get the required version of the Agda standard library from GitHub. You can either clone the repository and switch to the correct branch, or you can download the [the zip archive][agda-stdlib]:
|
||||
```bash
|
||||
git clone https://github.com/agda/agda-stdlib.git agda-stdlib
|
||||
cd agda-stdlib
|
||||
git checkout v1.3
|
||||
```
|
||||
You can get the latest version of Programming Language Foundations in Agda from GitHub, either by cloning the repository, or by downloading [the zip archive][plfa-dev]:
|
||||
```bash
|
||||
git clone https://github.com/plfa/plfa.github.io
|
||||
Finally, we need to let Agda know where to find the Agda standard library.
|
||||
You'll need the path where you installed the standard library, which we’ll refer to as “AGDA_STDLIB”. Check to see that the file “AGDA_STDLIB/standard-library.agda-lib” exists.
|
||||
You will need to create two configuration files in “AGDA_DIR”. On UNIX and macOS, “AGDA_DIR” defaults to “~/.agda”. On Windwos, “AGDA_DIR” usually defaults to “%AppData%\agda”, where “%AppData%” usually defaults to “C:\Users\USERNAME\AppData\Roaming”.
|
||||
|
||||
- If the “AGDA_DIR” directory does not already exist, create it.
|
||||
- In “AGDA_DIR”, create a plain-text file called “libraries” containing the path “AGDA_STDLIB/standard-library.agda-lib”. This lets Agda know that an Agda library called “standard-library” is available, at the path “AGDA_STDLIB”.
|
||||
- In “AGDA_DIR”, create a plain-text file called “defaults” containing *just* the line “standard-library”.
|
||||
|
||||
More information about placing the standard libraries is available from [the Library Management page][agda-docs-package-system] of the Agda documentation.
|
||||
|
||||
It is possible to set up PLFA as an Agda library as well. If you want to complete the exercises found in the “courses” folder, or to import modules from the book, you need to do this. To do so, add the path to “plfa.agda-lib” to “~/.agda/libraries” and add “plfa” to “~/.agda/defaults”, each on a line of their own.
|
||||
|
||||
#### Check if the Agda standard library was installed correctly
|
||||
If you’d like, you can test to see if you’ve installed the Agda standard library correctly. Create a file called “nats.agda” with these lines:
|
||||
```agda
|
||||
open import Data.Nat
|
||||
|
||||
ten : ℕ
|
||||
ten = 10
|
||||
```
|
||||
Finally, we need to let Agda know where to find the standard library. For this, you can follow the instructions [here][agda-docs-package-system].
|
||||
(Note that the ℕ is a Unicode character, not a plain capital N. You should be able to just copy-and-paste it from this page into your file.)
|
||||
|
||||
It is possible to set up PLFA as an Agda library as well. If you want to complete the exercises found in the `courses` folder, or to import modules from the book, you need to do this. To do so, add the path to `plfa.agda-lib` to `~/.agda/libraries` and add `plfa` to `~/.agda/defaults`, both on lines of their own.
|
||||
From a command line, change to the same directory where your “nats.agda” file is located. Then run:
|
||||
```bash
|
||||
agda -v 2 nats.agda
|
||||
```
|
||||
You should see a several lines describing the files which Agda loads while checking your file, but no errors:
|
||||
```
|
||||
Checking nats (/path/to/nats.agda).
|
||||
Loading Agda.Builtin.Equality (…).
|
||||
…
|
||||
Loading Data.Nat (…).
|
||||
Finished nats.
|
||||
```
|
||||
|
||||
|
||||
## Setting up and using Emacs
|
||||
## Setting up an editor for Agda
|
||||
|
||||
The recommended editor for Agda is Emacs with `agda-mode`. Agda ships with `agda-mode`, so if you’ve installed Agda, all you have to do to configure `agda-mode` is run:
|
||||
### Emacs
|
||||
The recommended editor for Agda is Emacs. To install Emacs:
|
||||
|
||||
- *On UNIX*, the version of Emacs in your repository is probably fine as long as it is fairly recent. There are also links to the most recent release on the [GNU Emacs downloads page][emacs].
|
||||
|
||||
- *On MacOS*, [Aquamacs][aquamacs] is probably the preferred version of Emacs, but GNU Emacs can also be installed via Homebrew or MacPorts. See the [GNU Emacs downloads page][emacs] for instructions.
|
||||
|
||||
- *On Windows*. See the [GNU Emacs downloads page][emacs] for instructions.
|
||||
|
||||
Make sure that you are able to open, edit, and save text files with your installation. The [tour of Emacs][emacstour] page on the GNU Emacs site describes how to access the tutorial within your Emacs installation.
|
||||
|
||||
Agda ships with the editor support for Emacs built-in, so if you’ve installed Agda, all you have to do to configure Emacs is run:
|
||||
```bash
|
||||
agda-mode setup
|
||||
agda-mode compile
|
||||
```
|
||||
If you are already an Emacs user and have customized your setup, you may want to note the configuration which the `setup` appends to your `.emacs` file, and integrate it with your own preferred setup.
|
||||
|
||||
#### Check if “agda-mode” was installed correctly
|
||||
Open the `nats.agda` file you created earlier, and load and type-check the file by typing [`C-c C-l`][agda-docs-emacs-notation].
|
||||
|
||||
#### Auto-loading “agda-mode” in Emacs
|
||||
Since version 2.6.0, Agda has had support for literate editing with Markdown, using the “.lagda.md” extension. One issue is that Emacs will default to Markdown editing mode for files with a “.md” suffix. In order to have “agda-mode” automatically loaded whenever you open a file ending with “.agda” or “.lagda.md”, add the following line to your Emacs configuration file:
|
||||
```elisp
|
||||
;; auto-load agda-mode for .agda and .lagda.md
|
||||
(setq auto-mode-alist
|
||||
(append
|
||||
'(("\\.agda\\'" . agda2-mode)
|
||||
("\\.lagda.md\\'" . agda2-mode))
|
||||
auto-mode-alist))
|
||||
```
|
||||
If you already have settings which change your “auto-mode-alist” in your configuration, put these *after* the ones you already have or combine them if you are comfortable with Emacs Lisp. The configuration file for Emacs is normally located in “~/.emacs” or “~/.emacs.d/init.el”, but Aquamacs users might need to move their startup settings to the “Preferences.el” file in “~/Library/Preferences/Aquamacs Emacs/Preferences”.
|
||||
|
||||
#### Optional: using the “mononoki” font with Emacs
|
||||
Agda uses Unicode characters for many key symbols, and it is important that the font which you use to view and edit Agda programs shows these symbols correctly. The most important part is that the font you use has good Unicode support, so while we recommend [mononoki][font-mononoki], fonts such as [Source Code Pro][font-sourcecodepro], [DejaVu Sans Mono][font-dejavusansmono], and [FreeMono][font-freemono] are all good alternatives.
|
||||
|
||||
You can download and install mononoki directly from [GitHub][mononoki]. For most systems, installing a font is merely a matter of clicking the downloaded “.otf” or “.ttf” file. If your package manager offers a package for mononoki, that might be easier. For instance, Homebrew on macOS offers the “font-mononoki” package, and APT on Debian offers the [“fonts-mononoki” package][font-mononoki-debian]. To configure Emacs to use mononoki as its default font, add the following to the end of your Emacs configuration file:
|
||||
``` elisp
|
||||
;; default to mononoki
|
||||
(set-face-attribute 'default nil
|
||||
:family "mononoki"
|
||||
:height 120
|
||||
:weight 'normal
|
||||
:width 'normal)
|
||||
```
|
||||
|
||||
#### Using “agda-mode” in Emacs
|
||||
To load and type-check the file, use [`C-c C-l`][agda-docs-emacs-notation].
|
||||
|
||||
Agda is edited interactively, using [“holes”][agda-docs-holes], which are bits of the program that are not yet filled in. If you use a question mark as an expression, and load the buffer using `C-c C-l`, Agda replaces the question mark with a hole. There are several things you can to while the cursor is in a hole:
|
||||
Agda is edited interactively, using [“holes”][agda-docs-holes], which are bits of the program that are not yet filled in. If you use a question mark as an expression, and load the buffer using “C-c C-l”, Agda replaces the question mark with a hole. There are several things you can to while the cursor is in a hole:
|
||||
|
||||
- `C-c C-c x`: **c**ase split on variable x
|
||||
- `C-c C-space`: fill in hole
|
||||
|
@ -86,47 +218,40 @@ If you want to see messages beside rather than below your Agda code, you can do
|
|||
|
||||
Now, error messages from Agda will appear next to your file, rather than squished beneath it.
|
||||
|
||||
#### Entering Unicode characters in Emacs with “agda-mode”
|
||||
When you write Agda code, you will need to insert characters which are not found on standard keyboards. Emacs “agda-mode” makes it easier to do this by defining character translations: when you enter certain sequences of ordinary characters (the kind you find on any keyboard), Emacs will replace them in your Agda file with the corresponding special character.
|
||||
|
||||
### Auto-loading `agda-mode` in Emacs
|
||||
|
||||
Since version 2.6.0, Agda has support for literate editing with Markdown, using the `.lagda.md` extension. One side-effect of this extension is that most editors default to Markdown editing mode, whereas
|
||||
In order to have `agda-mode` automatically loaded whenever you open a file ending with `.agda` or `.lagda.md`, put the following on your Emacs configuration file:
|
||||
```elisp
|
||||
(setq auto-mode-alist
|
||||
(append
|
||||
'(("\\.agda\\'" . agda2-mode)
|
||||
("\\.lagda.md\\'" . agda2-mode))
|
||||
auto-mode-alist))
|
||||
For example, we can add a comment line to one of the “.agda” test files. Let's say we want to add a comment line that reads:
|
||||
```
|
||||
|
||||
(The configuration file for Emacs is normally located in `~/.emacs` or `~/.emacs.d/init.el`, but Aquamacs users might need to move their startup settings to the `Preferences.el` file in `~/Library/Preferences/Aquamacs Emacs/Preferences`.)
|
||||
|
||||
|
||||
### Using mononoki in Emacs
|
||||
|
||||
It is recommended that you install the font [mononoki][mononoki], and add the following to the end of your emacs configuration file at `~/.emacs`:
|
||||
|
||||
``` elisp
|
||||
;; default to mononoki
|
||||
(set-face-attribute 'default nil
|
||||
:family "mononoki"
|
||||
:height 120
|
||||
:weight 'normal
|
||||
:width 'normal)
|
||||
{- I am excited to type ∀ and → and ≤ and ≡ !! -}
|
||||
```
|
||||
The first few characters are ordinary, so we would just type them as usual:
|
||||
```
|
||||
{- I am excited to type
|
||||
```
|
||||
But after that last space, we do not find ∀ on the keyboard. The code for this character is the four characters `\all`, so we type those four characters, and when we finish, Emacs will replace them with what we want:
|
||||
```
|
||||
{- I am excited to type ∀
|
||||
```
|
||||
We can continue with the codes for the other characters. Sometimes the characters will change as we type them, because a prefix of our character's code is the code of another character. This happens with the arrow, whose code is `\->`. After typing `\-` we see:
|
||||
```
|
||||
{- I am excited to type ∀ and
|
||||
```
|
||||
because the code `\-` corresponds to a hyphen of a certain width. When we add the `>`, the `` becomes `→`! The code for `≤` is `\<=`, and the code for `≡` is `\==`.
|
||||
```
|
||||
{- I am excited to type ∀ and → and ≤ and ≡
|
||||
```
|
||||
Finally the last few characters are ordinary again,
|
||||
```
|
||||
{- I am excited to type ∀ and → and ≤ and ≡ !! -}
|
||||
```
|
||||
If you're having trouble typing the Unicode characters into Emacs, the end of each chapter should provide a list of the Unicode characters introduced in that chapter.
|
||||
|
||||
|
||||
### Unicode characters
|
||||
|
||||
If you're having trouble typing the Unicode characters into Emacs, the end of each chapter should provide a list of the unicode characters introduced in that chapter.
|
||||
|
||||
`agda-mode` and emacs have a number of useful commands. Two of them are especially useful when you solve exercises.
|
||||
|
||||
For a full list of supported characters, use `agda-input-show-translations` with:
|
||||
Emacs with “agda-mode” offers a number of useful commands, and two of them are especially useful when it comes to working with Unicode characters. For a full list of supported characters, use “agda-input-show-translations” with:
|
||||
|
||||
M-x agda-input-show-translations
|
||||
|
||||
All the supported characters in `agda-mode` are shown.
|
||||
All the supported characters in “agda-mode” are shown.
|
||||
|
||||
If you want to know how you input a specific Unicode character in agda file, move the cursor onto the character and type the following command:
|
||||
|
||||
|
@ -136,86 +261,60 @@ You'll see the key sequence of the character in mini buffer.
|
|||
|
||||
|
||||
## Dependencies for developers
|
||||
PLFA is written in literate Agda with [Pandoc Markdown][pandoc].
|
||||
PLFA is available as both a website and an EPUB e-book, both of which can be built on UNIX and macOS.
|
||||
Finally, to help developers avoid common mistakes, we provide a set of Git hooks.
|
||||
|
||||
PLFA is available as both a website and an EPUB e-book, both of which can be built on Linux and macOS.
|
||||
PLFA is written in literate Agda with [Kramdown Markdown][kramdown].
|
||||
|
||||
### Building the website and e-book
|
||||
If you’d like to build the web version of PLFA locally, [Stack](#install-the-haskell-tool-stack) is all you need! PLFA is built using [Hakyll][hakyll], a Haskell library for building static websites. We’ve setup a Makefile to help you run common tasks. For instance, to build PLFA, run:
|
||||
```bash
|
||||
make build
|
||||
```
|
||||
If you’d like to serve PLFA locally, rebuilding the website when any of the source files are changed, run:
|
||||
```bash
|
||||
make watch
|
||||
```
|
||||
The Makefile offers more than just building and watching, it also offers the following useful options:
|
||||
```
|
||||
build # Build PLFA
|
||||
watch # Build and serve PLFA, monitor for changes and rebuild
|
||||
test # Test web version for broken links, invalid HTML, etc.
|
||||
test-epub # Test EPUB for compliance to the EPUB3 standard
|
||||
clean # Clean PLFA build
|
||||
init # Setup the Git hooks (see below)
|
||||
update-contributors # Pull in new contributors from GitHub to contributors/
|
||||
list # List all build targets
|
||||
```
|
||||
For completeness, the Makefile also offers the following options, but you’re unlikely to need these:
|
||||
```
|
||||
legacy-versions # Build legacy versions of PLFA
|
||||
setup-install-bundler # Install Ruby Bundler (needed for ‘legacy-versions’)
|
||||
setup-install-htmlproofer # Install HTMLProofer (needed for ‘test’ and Git hooks)
|
||||
setup-check-fix-whitespace # Check to see if fix-whitespace is installed (needed for Git hooks)
|
||||
setup-check-epubcheck # Check to see if epubcheck is installed (needed for EPUB tests)
|
||||
setup-check-gem # Check to see if RubyGems is installed
|
||||
setup-check-npm # Check to see if the Node Package Manager is installed
|
||||
setup-check-stack # Check to see if the Haskell Tool Stack is installed
|
||||
```
|
||||
The [EPUB version][epub] of the book is built as part of the website, since it’s hosted on the website.
|
||||
|
||||
|
||||
### Git hooks
|
||||
|
||||
The repository comes with several Git hooks:
|
||||
|
||||
1. The [fix-whitespace][fix-whitespace] program is run to check for whitespace violations.
|
||||
|
||||
2. The test suite is run to check if everything type checks.
|
||||
|
||||
You can install these Git hooks by calling `make init`.
|
||||
You can install these Git hooks by calling “make init”.
|
||||
You can install [fix-whitespace][fix-whitespace] by running:
|
||||
```bash
|
||||
git clone https://github.com/agda/fix-whitespace
|
||||
cd fix-whitespace/
|
||||
stack install --stack-yaml stack-8.8.3.yaml
|
||||
```
|
||||
If you want Stack to use your system installation of GHC, you can pass the `--system-ghc` flag and select the appropriate `stack-*.yaml` file, like when installing [Agda](#installing-agda-using-stack).
|
||||
|
||||
|
||||
### Building the website
|
||||
|
||||
The website version of the book is built in three stages:
|
||||
|
||||
1. The `.lagda.md` files are compiled to Markdown using Agda’s highlighter.
|
||||
(This requires several POSIX tools, such as `bash`, `sed`, and `grep`.)
|
||||
|
||||
2. The Markdown files are converted to HTML using [Jekyll][ruby-jekyll], a widely-used static site builder.
|
||||
(This requires [Ruby][ruby] and [Jekyll][ruby-jekyll].)
|
||||
|
||||
3. The HTML is checked using [html-proofer][ruby-html-proofer].
|
||||
(This requires [Ruby][ruby] and [html-proofer][ruby-html-proofer].)
|
||||
|
||||
Most recent versions of [Ruby][ruby] should work. The easiest way to install [Jekyll][ruby-jekyll] and [html-proofer][ruby-html-proofer] is using [Bundler][ruby-bundler]. You can install [Bundler][ruby-bundler] by running:
|
||||
```bash
|
||||
gem install bundler
|
||||
```
|
||||
You can install the remainder of the dependencies—[Jekyll][ruby-jekyll], [html-proofer][ruby-html-proofer], *etc.*—by running:
|
||||
```bash
|
||||
bundle install
|
||||
```
|
||||
Once you have installed all of the dependencies, you can build a copy of the book, and host it locally, by running:
|
||||
```bash
|
||||
make build
|
||||
make serve
|
||||
```
|
||||
The Makefile offers more than just these options:
|
||||
```bash
|
||||
make # see make test
|
||||
make build # builds lagda->markdown and the website
|
||||
make build-incremental # builds lagda->markdown and the website incrementally
|
||||
make test # checks all links are valid
|
||||
make test-offline # checks all links are valid offline
|
||||
make serve # starts the server
|
||||
make server-start # starts the server in detached mode
|
||||
make server-stop # stops the server, uses pkill
|
||||
make clean # removes all ~unnecessary~ generated files
|
||||
make clobber # removes all generated files
|
||||
```
|
||||
If you simply wish to have a local copy of the book, e.g. for offline reading, but don't care about editing and rebuilding the book, you can grab a copy of the [master branch][plfa-master], which is automatically built using Travis. You will still need [Jekyll][ruby-jekyll] and preferably [Bundler][ruby-bundler] to host the book (see above). To host the book this way, download a copy of the [master branch][plfa-master], unzip, and from within the directory run
|
||||
```bash
|
||||
bundle install
|
||||
bundle exec jekyll serve
|
||||
```
|
||||
|
||||
|
||||
### Building the EPUB
|
||||
|
||||
The [EPUB version][epub] of the book is built using Pandoc.
|
||||
|
||||
Install a recent version of Pandoc, [available here][pandoc]. The easiest way to install Pandoc is using their official installer, which is much faster than compiling Pandoc from source with Haskell Stack.
|
||||
|
||||
Once you’ve installed Pandoc, you can build the EPUB by running:
|
||||
```bash
|
||||
make epub
|
||||
```
|
||||
The EPUB is written to `out/epub/plfa.epub`.
|
||||
If you want Stack to use your system installation of GHC, follow the instructions for [Using an existing installation of GHC](#using-an-existing-installation-of-ghc).
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
|
@ -227,29 +326,31 @@ The EPUB is written to `out/epub/plfa.epub`.
|
|||
[plfa-calver]: https://img.shields.io/badge/calver-20.07-22bfda
|
||||
[plfa-latest]: https://github.com/plfa/plfa.github.io/releases/latest
|
||||
[plfa-master]: https://github.com/plfa/plfa.github.io/archive/master.zip
|
||||
|
||||
[haskell-stack]: https://docs.haskellstack.org/en/stable/README/
|
||||
[haskell-ghc]: https://www.haskell.org/ghc/
|
||||
[git]: https://git-scm.com/downloads
|
||||
[agda]: https://github.com/agda/agda/releases/tag/v2.6.1
|
||||
[agda-version]: https://img.shields.io/badge/agda-v2.6.1-blue.svg
|
||||
[agda-docs-holes]: https://agda.readthedocs.io/en/v2.5.4/getting-started/quick-guide.html
|
||||
[agda-docs-emacs-mode]: https://agda.readthedocs.io/en/v2.6.1/tools/emacs-mode.html
|
||||
[agda-docs-emacs-notation]: https://agda.readthedocs.io/en/v2.6.1/tools/emacs-mode.html#notation-for-key-combinations
|
||||
[agda-docs-package-system]: https://agda.readthedocs.io/en/v2.6.1/tools/package-system.html#example-using-the-standard-library
|
||||
|
||||
[emacs]: https://www.gnu.org/software/emacs/download.html
|
||||
[emacstour]: https://www.gnu.org/software/emacs/tour/
|
||||
[aquamacs]: http://aquamacs.org/
|
||||
[agda-stdlib-version]: https://img.shields.io/badge/agda--stdlib-v1.3-blue.svg
|
||||
[agda-stdlib]: https://github.com/agda/agda-stdlib/releases/tag/v1.3
|
||||
|
||||
[haskell-stack]: https://docs.haskellstack.org/en/stable/README/
|
||||
[haskell-ghc]: https://www.haskell.org/ghc/
|
||||
|
||||
[fix-whitespace]: https://github.com/agda/fix-whitespace
|
||||
|
||||
[mononoki]: https://madmalik.github.io/mononoki/
|
||||
|
||||
[ruby]: https://www.ruby-lang.org/en/documentation/installation/
|
||||
[ruby-bundler]: https://bundler.io/#getting-started
|
||||
[ruby-jekyll]: https://jekyllrb.com/
|
||||
[ruby-html-proofer]: https://github.com/gjtorikian/html-proofer
|
||||
|
||||
[kramdown]: https://kramdown.gettalong.org/syntax.html
|
||||
[hakyll]: https://jaspervdj.be/hakyll/
|
||||
[pandoc]: https://pandoc.org/installing.html
|
||||
[epubcheck]: https://github.com/w3c/epubcheck
|
||||
[xcode]: https://developer.apple.com/xcode/
|
||||
[font-sourcecodepro]: https://github.com/adobe-fonts/source-code-pro
|
||||
[font-dejavusansmono]: https://dejavu-fonts.github.io/
|
||||
[font-freemono]: https://www.gnu.org/software/freefont/
|
||||
[font-mononoki]: https://madmalik.github.io/mononoki/
|
||||
[font-mononoki-debian]: https://packages.debian.org/sid/fonts/fonts-mononoki
|
||||
|
|
23
TODO.md
Normal file
23
TODO.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Roadmap
|
||||
|
||||
Here’s what still needs to happen in order to use Hakyll for PLFA builds.
|
||||
We can release after the first milestone.
|
||||
The goals in the second milestone are optional, but nice.
|
||||
|
||||
|
||||
## Milestone 1
|
||||
|
||||
- migrate EPUB generation over to site.hs
|
||||
|
||||
|
||||
## Milestone 2
|
||||
|
||||
- automatically generate Unicode sections
|
||||
+ use a context field similar to the teaser context
|
||||
+ create a template for book chapters which uses said field
|
||||
+ use book chapter template for .lagda.md files
|
||||
|
||||
- automatically generate Statistics chapter
|
||||
+ see https://github.com/plfa/plfa.github.io/blob/41939ad0312b6012ac76f056c6da1f9ff590c040/hs/agda-count.hs
|
||||
|
||||
- …
|
71
_config.yml
71
_config.yml
|
@ -1,71 +0,0 @@
|
|||
title: >
|
||||
Programming Language Foundations in Agda
|
||||
|
||||
description: >
|
||||
Programming Language Foundations in Agda
|
||||
|
||||
license: Creative Commons Attribution 4.0 International License
|
||||
license-file: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# To include a new author, add them below in the order in which they are to be
|
||||
# displayed in the author list. If they have made contributions as an author via
|
||||
# GitHub, their username MUST be included in the list.
|
||||
authors:
|
||||
- name: Philip Wadler
|
||||
email: wadler@inf.ed.ac.uk
|
||||
corresponding: true
|
||||
github_username: wadler
|
||||
- name: Wen Kokke
|
||||
email: wen.kokke@ed.ac.uk
|
||||
corresponding: true
|
||||
github_username: wenkokke
|
||||
twitter_username: wenkokke
|
||||
- name: Jeremy G. Siek
|
||||
email: jsiek@indiana.edu
|
||||
corresponding: true
|
||||
github_username: jsiek
|
||||
twitter_username: jeremysiek
|
||||
|
||||
extra_contributors:
|
||||
- github_username: cyberglot
|
||||
- name: Vikraman Choudhury
|
||||
- name: Ben Darwin
|
||||
- github_username: koo5
|
||||
- name: Anish Tondwalkar
|
||||
- name: Nils Anders Danielsson
|
||||
- name: Miëtek Bak
|
||||
- name: Gergő Érdi
|
||||
- name: Adam Sandberg Eriksson
|
||||
- name: David Janin
|
||||
- name: András Kovács
|
||||
- name: Ulf Norell
|
||||
- name: Liam O'Connor
|
||||
- name: N. Raghavendra
|
||||
- name: Roman Kireev
|
||||
- name: Amr Sabry
|
||||
|
||||
google_analytics: "UA-125055580-1"
|
||||
|
||||
repository: plfa/plfa.github.io
|
||||
branch: dev
|
||||
|
||||
baseurl: ""
|
||||
url: "https://plfa.github.io"
|
||||
markdown: kramdown
|
||||
theme: minima
|
||||
excerpt_separator: <!--more-->
|
||||
exclude:
|
||||
- "*.lagda.md"
|
||||
- "*.agdai"
|
||||
- "*.agda-lib"
|
||||
- "extra/"
|
||||
- "papers/"
|
||||
- "vendor/"
|
||||
- "epub/"
|
||||
- ".versions/"
|
||||
- "_build/"
|
||||
- "Guardfile"
|
||||
- "Gemfile"
|
||||
- "Gemfile.lock"
|
||||
- "highlight.sh"
|
||||
- "out/epub/acknowledgements.md"
|
|
@ -1,36 +0,0 @@
|
|||
<footer class="site-footer h-card">
|
||||
<data class="u-url" href="{{ "/" | relative_url }}"></data>
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<h2 class="footer-heading">{{ site.title | escape }}</h2>
|
||||
|
||||
{%- for author in site.authors -%}
|
||||
{%- if author.corresponding -%}
|
||||
<div class="footer-col-wrapper">
|
||||
<div class="footer-col footer-col-1">
|
||||
<ul class="contact-list">
|
||||
<li class="p-name">{{ author.name | escape }}</li>
|
||||
<li>
|
||||
{%- if author.email -%}
|
||||
<a class="u-email" href="mailto:{{ author.email }}">{{ author.email }}</a>
|
||||
{%- endif -%}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="footer-col footer-col-2">
|
||||
{%- include social.html -%}
|
||||
</div>
|
||||
|
||||
<div class="footer-col footer-col-3">
|
||||
{%- if author.blurb -%}
|
||||
<p>{{- author.blurb | escape -}}</p>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
</div>
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
This work is licensed under a <a rel="license" href="{{ site.license-file }}">{{ site.license }}</a>
|
||||
</div>
|
||||
</footer>
|
|
@ -1,17 +0,0 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>
|
||||
{%- if page.layout == 'home' -%}
|
||||
{{ site.title }}
|
||||
{%- else -%}
|
||||
{{ page.title }} | {{ site.title }}
|
||||
{%- endif -%}
|
||||
</title>
|
||||
{%- seo title=false -%}
|
||||
<link rel="stylesheet" href="{{ "/assets/main.css" | relative_url }}">
|
||||
{%- if jekyll.environment == 'production' and site.google_analytics -%}
|
||||
{%- include google-analytics.html -%}
|
||||
{%- endif -%}
|
||||
</head>
|
|
@ -1,17 +0,0 @@
|
|||
<p style="text-align:center;">
|
||||
{% if page.prev %}
|
||||
<a alt="Previous chapter" href="{{ site.baseurl }}{{ page.prev }}">Prev</a>
|
||||
{% endif %}
|
||||
{% if page.prev and (page.src or page.next) %}
|
||||
•
|
||||
{% endif %}
|
||||
{% if page.src %}
|
||||
<a alt="Source code" href="https://github.com/{{ site.repository }}/blob/{{ site.branch }}/{{ page.src }}">Source</a>
|
||||
{% endif %}
|
||||
{% if page.src and page.next %}
|
||||
•
|
||||
{% endif %}
|
||||
{% if page.next %}
|
||||
<a alt="Next chapter" href="{{ site.baseurl }}{{ page.next }}">Next</a>
|
||||
{% endif %}
|
||||
</p>
|
|
@ -1,77 +0,0 @@
|
|||
<!-- Import jQuery -->
|
||||
<script type="text/javascript" src="{{ "/assets/jquery.js" | prepend: site.baseurl }}"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/4.2.2/anchor.min.js" integrity="sha256-E4RlfxwyJVmkkk0szw7LYJxuPlp6evtPSBDlWHsYYL8=" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript">
|
||||
// Add anchors on DOMContentLoaded
|
||||
document.addEventListener('DOMContentLoaded', function(event) {
|
||||
anchors.add();
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
// Script which allows for foldable code blocks
|
||||
$('div.foldable pre').each(function(){
|
||||
var autoHeight = $(this).height();
|
||||
var lineHeight = parseFloat($(this).css('line-height'));
|
||||
|
||||
var plus = $("<div></div>");
|
||||
var horLine = $("<div></div>");
|
||||
var verLine = $("<div></div>");
|
||||
$(this).prepend(plus);
|
||||
plus.css({
|
||||
'position' : 'relative',
|
||||
'float' : 'right',
|
||||
'right' : '-' + (0.5 * lineHeight - 1.5) + 'px',
|
||||
'width' : lineHeight,
|
||||
'height' : lineHeight});
|
||||
verLine.css({
|
||||
'position' : 'relative',
|
||||
'height' : lineHeight,
|
||||
'width' : '3px',
|
||||
'background-color' : '#C1E0FF'});
|
||||
horLine.css({
|
||||
'position' : 'relative',
|
||||
'top' : '-' + (0.5 * lineHeight + 1.5) + 'px',
|
||||
'left' : '-' + (0.5 * lineHeight - 1.5) + 'px',
|
||||
'height' : '3px',
|
||||
'width' : lineHeight,
|
||||
'background-color' : '#C1E0FF'});
|
||||
plus.append(verLine);
|
||||
plus.append(horLine);
|
||||
|
||||
$(this).height(2.0 * lineHeight);
|
||||
$(this).css('overflow','hidden');
|
||||
|
||||
$(this).click(function(){
|
||||
if ($(this).height() == autoHeight) {
|
||||
$(this).height(2.0 * lineHeight);
|
||||
plus.show();
|
||||
}
|
||||
else {
|
||||
$(this).height('auto');
|
||||
plus.hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Import KaTeX -->
|
||||
<script type="text/javascript" src="{{ "/assets/katex.js" | prepend: site.baseurl }}"></script>
|
||||
|
||||
<!-- Script which renders TeX using KaTeX -->
|
||||
<script type="text/javascript">
|
||||
$("script[type='math/tex']").replaceWith(
|
||||
function(){
|
||||
var tex = $(this).text();
|
||||
return "<span class=\"inline-equation\">" +
|
||||
katex.renderToString(tex) +
|
||||
"</span>";
|
||||
});
|
||||
$("script[type='math/tex; mode=display']").replaceWith(
|
||||
function(){
|
||||
var tex = $(this).text().replace(/%.*?(\n|$)/g,"");
|
||||
return "<div class=\"equation\">" +
|
||||
katex.renderToString("\\displaystyle "+tex) +
|
||||
"</div>";
|
||||
});
|
||||
</script>
|
|
@ -1,13 +0,0 @@
|
|||
<ul class="social-media-list">
|
||||
{%- if author.dribbble_username -%}<li><a href="https://dribbble.com/{{ author.dribbble_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#dribbble' | relative_url }}"></use></svg> <span class="username">{{ author.dribbble_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if author.facebook_username -%}<li><a href="https://www.facebook.com/{{ author.facebook_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#facebook' | relative_url }}"></use></svg> <span class="username">{{ author.facebook_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if author.flickr_username -%}<li><a href="https://www.flickr.com/photos/{{ author.flickr_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#flickr' | relative_url }}"></use></svg> <span class="username">{{ author.flickr_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if author.github_username -%}<li><a href="https://github.com/{{ author.github_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#github' | relative_url }}"></use></svg> <span class="username">{{ author.github_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if author.instagram_username -%}<li><a href="https://instagram.com/{{ author.instagram_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#instagram' | relative_url }}"></use></svg> <span class="username">{{ author.instagram_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if author.linkedin_username -%}<li><a href="https://www.linkedin.com/in/{{ author.linkedin_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#linkedin' | relative_url }}"></use></svg> <span class="username">{{ author.linkedin_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if author.pinterest_username -%}<li><a href="https://www.pinterest.com/{{ author.pinterest_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#pinterest' | relative_url }}"></use></svg> <span class="username">{{ author.pinterest_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- for mst in author.mastodon -%}{%- if mst.username and mst.instance -%}<li><a href="https://{{ mst.instance| cgi_escape | escape}}/@{{mst.username}}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#mastodon' | relative_url }}"></use></svg> <span class="username">{{ mst.username|escape }}</span></a></li>{%- endif -%}{%- endfor -%}
|
||||
{%- if author.twitter_username -%}<li><a href="https://www.twitter.com/{{ author.twitter_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#twitter' | relative_url }}"></use></svg> <span class="username">{{ author.twitter_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if author.youtube_username -%}<li><a href="https://youtube.com/{{ author.youtube_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#youtube' | relative_url }}"></use></svg> <span class="username">{{ author.youtube_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if author.googleplus_username -%}<li><a href="https://plus.google.com/{{ author.googleplus_username| escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#googleplus' | relative_url }}"></use></svg> <span class="username">{{ author.googleplus_username| escape }}</span></a></li>{%- endif -%}
|
||||
</ul>
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ page.lang | default: site.lang | default: "en" }}">
|
||||
|
||||
{%- include head.html -%}
|
||||
|
||||
<body>
|
||||
|
||||
{%- include header.html -%}
|
||||
|
||||
<main class="page-content" aria-label="Content">
|
||||
<div class="wrapper">
|
||||
{{ content }}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{%- include footer.html -%}
|
||||
|
||||
<script type="text/javascript">
|
||||
// Fix sandwich menu
|
||||
$('.menu-icon').click(function(){
|
||||
$('.trigger').toggle();
|
||||
});
|
||||
</script>
|
||||
|
||||
{%- include script.html -%}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,30 +0,0 @@
|
|||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
<div class="home">
|
||||
|
||||
{{ content }}
|
||||
|
||||
{%- if site.posts.size > 0 -%}
|
||||
<h1 class="post-list-heading">Announcements</h1>
|
||||
<ul class="post-list">
|
||||
{%- for post in site.posts -%}
|
||||
<li>
|
||||
{%- assign date_format = site.minima.date_format | default: "%b %-d, %Y" -%}
|
||||
<span class="post-meta">{{ post.date | date: date_format }}</span>
|
||||
<h2>{{ post.title | escape }}</h2>
|
||||
{%- if post.short -%}
|
||||
{{ post.excerpt }}
|
||||
{%- else -%}
|
||||
{{ post.excerpt }}
|
||||
<a href="{{ post.url | relative_url }}">(more)</a>
|
||||
{%- endif -%}
|
||||
</li>
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
|
||||
<p class="feed-subscribe"><svg class="svg-icon orange"><use xlink:href="{{ '/assets/minima-social-icons.svg#rss' | relative_url }}"></use></svg><a href="{{ "/feed.xml" | relative_url }}">Subscribe</a></p>
|
||||
{%- endif -%}
|
||||
|
||||
</div>
|
|
@ -1,19 +0,0 @@
|
|||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
<article class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">{{ page.title | escape }}</h1>
|
||||
</header>
|
||||
|
||||
{% include next.html %}
|
||||
|
||||
<div class="post-content">
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
{% include next.html %}
|
||||
|
||||
</article>
|
|
@ -1,27 +0,0 @@
|
|||
---
|
||||
layout: default
|
||||
---
|
||||
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title p-name" itemprop="name headline">{{ page.title | escape }}</h1>
|
||||
<p class="post-meta">
|
||||
<time class="dt-published" datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">
|
||||
{%- assign date_format = site.minima.date_format | default: "%b %-d, %Y" -%}
|
||||
{{ page.date | date: date_format }}
|
||||
</time>
|
||||
{%- if page.author -%}
|
||||
• <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span class="p-author h-card" itemprop="name">{{ page.author | escape }}</span></span>
|
||||
{%- endif -%}</p>
|
||||
</header>
|
||||
|
||||
<div class="post-content e-content" itemprop="articleBody">
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
{%- if site.disqus.shortname -%}
|
||||
{%- include disqus_comments.html -%}
|
||||
{%- endif -%}
|
||||
|
||||
<a class="u-url" href="{{ page.url | relative_url }}" hidden></a>
|
||||
</article>
|
File diff suppressed because one or more lines are too long
|
@ -1,28 +0,0 @@
|
|||
---
|
||||
# Only the main Sass file needs front matter (the dashes are enough)
|
||||
---
|
||||
@import "katex";
|
||||
@import "minima";
|
||||
@import "agda";
|
||||
|
||||
$on-medium: 600px !default;
|
||||
|
||||
.trigger { display: none; }
|
||||
|
||||
@media screen and (min-width: $on-medium) {
|
||||
.trigger { display: block; }
|
||||
}
|
||||
|
||||
ul.list-of-contributors {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
width: calc(100% - 2rem);
|
||||
}
|
||||
|
||||
ul.list-of-contributors li {
|
||||
margin-right: 2rem;
|
||||
}
|
||||
|
||||
pre {
|
||||
break-inside: avoid;
|
||||
}
|
7
authors/jsiek.metadata
Normal file
7
authors/jsiek.metadata
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name : Jeremy G. Siek
|
||||
email : jsiek@indiana.edu
|
||||
corresponding : true
|
||||
github : jsiek
|
||||
twitter : jeremysiek
|
||||
---
|
6
authors/wadler.metadata
Normal file
6
authors/wadler.metadata
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
name : Philip Wadler
|
||||
email : wadler@inf.ed.ac.uk
|
||||
corresponding : true
|
||||
github : wadler
|
||||
---
|
7
authors/wenkokke.metadata
Normal file
7
authors/wenkokke.metadata
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name : Wen Kokke
|
||||
email : wen.kokke@ed.ac.uk
|
||||
corresponding : true
|
||||
github : wenkokke
|
||||
twitter : wenkokke
|
||||
---
|
5
contributors/AD1024.metadata
Normal file
5
contributors/AD1024.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: Mike He
|
||||
github: AD1024
|
||||
---
|
5
contributors/AndrasKovacs.metadata
Normal file
5
contributors/AndrasKovacs.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: András Kovács
|
||||
github: AndrasKovacs
|
||||
count: 1
|
||||
---
|
5
contributors/ChefYeum.metadata
Normal file
5
contributors/ChefYeum.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Dee Yeum
|
||||
github: ChefYeum
|
||||
---
|
5
contributors/Cubesoup.metadata
Normal file
5
contributors/Cubesoup.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 12
|
||||
name: Chad Nester
|
||||
github: Cubesoup
|
||||
---
|
5
contributors/Fingerzam.metadata
Normal file
5
contributors/Fingerzam.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 7
|
||||
name: Juhana Laurinharju
|
||||
github: Fingerzam
|
||||
---
|
5
contributors/GaganSD.metadata
Normal file
5
contributors/GaganSD.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Gagan Devagiri
|
||||
github: GaganSD
|
||||
---
|
5
contributors/Kwezan.metadata
Normal file
5
contributors/Kwezan.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 36
|
||||
name: Zbigniew Stanasiuk
|
||||
github: Kwezan
|
||||
---
|
5
contributors/L-TChen.metadata
Normal file
5
contributors/L-TChen.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: Liang-Ting Chen
|
||||
github: L-TChen
|
||||
---
|
5
contributors/LightAndLight.metadata
Normal file
5
contributors/LightAndLight.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: Isaac Elliott
|
||||
github: LightAndLight
|
||||
---
|
5
contributors/MatthiasGabriel.metadata
Normal file
5
contributors/MatthiasGabriel.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: Matthias Gabriel
|
||||
github: MatthiasGabriel
|
||||
---
|
5
contributors/OlingCat.metadata
Normal file
5
contributors/OlingCat.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Oling Cat
|
||||
github: OlingCat
|
||||
---
|
5
contributors/Teggy.metadata
Normal file
5
contributors/Teggy.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Torsten Grust
|
||||
github: Teggy
|
||||
---
|
5
contributors/UlfNorell.metadata
Normal file
5
contributors/UlfNorell.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Ulf Norell
|
||||
github: UlfNorell
|
||||
count: 1
|
||||
---
|
5
contributors/abrisan.metadata
Normal file
5
contributors/abrisan.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 4
|
||||
name: Alexandru Brisan
|
||||
github: abrisan
|
||||
---
|
5
contributors/adamse.metadata
Normal file
5
contributors/adamse.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Adam Sandberg Eriksson
|
||||
github: adamse
|
||||
count: 1
|
||||
---
|
5
contributors/atondwal.metadata
Normal file
5
contributors/atondwal.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Anish Tondwalkar
|
||||
github: atondwal
|
||||
count: 1
|
||||
---
|
5
contributors/bcdarwin.metadata
Normal file
5
contributors/bcdarwin.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Ben Darwin
|
||||
github: bcdarwin
|
||||
count: 1
|
||||
---
|
5
contributors/caryoscelus.metadata
Normal file
5
contributors/caryoscelus.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 3
|
||||
name: caryoscelus
|
||||
github: caryoscelus
|
||||
---
|
5
contributors/chikeabuah.metadata
Normal file
5
contributors/chikeabuah.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Chike Abuah
|
||||
github: chikeabuah
|
||||
---
|
5
contributors/citrusmunch.metadata
Normal file
5
contributors/citrusmunch.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: citrusmunch
|
||||
github: citrusmunch
|
||||
---
|
5
contributors/cyberglot.metadata
Normal file
5
contributors/cyberglot.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: April Gonçalves
|
||||
github: cyberglot
|
||||
count: 1
|
||||
---
|
5
contributors/dalpd.metadata
Normal file
5
contributors/dalpd.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Deniz Alp
|
||||
github: dalpd
|
||||
---
|
5
contributors/djanin.metadata
Normal file
5
contributors/djanin.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: David Janin
|
||||
github: djanin
|
||||
count: 1
|
||||
---
|
5
contributors/effectfully.metadata
Normal file
5
contributors/effectfully.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Roman Kireev
|
||||
github: effectfully
|
||||
count: 1
|
||||
---
|
5
contributors/fangyi-zhou.metadata
Normal file
5
contributors/fangyi-zhou.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 8
|
||||
name: Fangyi Zhou
|
||||
github: fangyi-zhou
|
||||
---
|
5
contributors/gallais.metadata
Normal file
5
contributors/gallais.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: G. Allais
|
||||
github: gallais
|
||||
---
|
5
contributors/gergoerdi.metadata
Normal file
5
contributors/gergoerdi.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Gergő Érdi
|
||||
github: gergoerdi
|
||||
count: 1
|
||||
---
|
5
contributors/googleson78.metadata
Normal file
5
contributors/googleson78.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Georgi Lyubenov
|
||||
github: googleson78
|
||||
---
|
5
contributors/gshen42.metadata
Normal file
5
contributors/gshen42.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Gan Shen
|
||||
github: gshen42
|
||||
---
|
5
contributors/h4iku.metadata
Normal file
5
contributors/h4iku.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 28
|
||||
name: Reza Gharibi
|
||||
github: h4iku
|
||||
---
|
5
contributors/hugomg.metadata
Normal file
5
contributors/hugomg.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Hugo Gualandi
|
||||
github: hugomg
|
||||
---
|
5
contributors/iblech.metadata
Normal file
5
contributors/iblech.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: Ingo Blechschmidt
|
||||
github: iblech
|
||||
---
|
5
contributors/jonaprieto.metadata
Normal file
5
contributors/jonaprieto.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 4
|
||||
name: Jonathan Prieto
|
||||
github: jonaprieto
|
||||
---
|
5
contributors/jphmrst.metadata
Normal file
5
contributors/jphmrst.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: John Maraist
|
||||
github: jphmrst
|
||||
---
|
5
contributors/k4rtik.metadata
Normal file
5
contributors/k4rtik.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Kartik Singhal
|
||||
github: k4rtik
|
||||
---
|
5
contributors/kenichi-asai.metadata
Normal file
5
contributors/kenichi-asai.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 5
|
||||
name: Kenichi Asai
|
||||
github: kenichi-asai
|
||||
---
|
5
contributors/koo5.metadata
Normal file
5
contributors/koo5.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: koo5
|
||||
github: koo5
|
||||
count: 1
|
||||
---
|
5
contributors/kranich.metadata
Normal file
5
contributors/kranich.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Stefan Kranich
|
||||
github: kranich
|
||||
---
|
5
contributors/kwxm.metadata
Normal file
5
contributors/kwxm.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Kenneth MacKenzie
|
||||
github: kwxm
|
||||
---
|
5
contributors/laMudri.metadata
Normal file
5
contributors/laMudri.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: James Wood
|
||||
github: laMudri
|
||||
---
|
5
contributors/liamoc.metadata
Normal file
5
contributors/liamoc.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Liam O'Connor
|
||||
github: liamoc
|
||||
count: 1
|
||||
---
|
5
contributors/lzmartinico.metadata
Normal file
5
contributors/lzmartinico.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 3
|
||||
name: Lorenzo Martinico
|
||||
github: lzmartinico
|
||||
---
|
5
contributors/matthew-healy.metadata
Normal file
5
contributors/matthew-healy.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 3
|
||||
name: Matthew Healy
|
||||
github: matthew-healy
|
||||
---
|
5
contributors/mdimjasevic.metadata
Normal file
5
contributors/mdimjasevic.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 114
|
||||
name: Marko Dimjašević
|
||||
github: mdimjasevic
|
||||
---
|
5
contributors/mgttlinger.metadata
Normal file
5
contributors/mgttlinger.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Merlin Göttlinger
|
||||
github: mgttlinger
|
||||
---
|
5
contributors/michel-steuwer.metadata
Normal file
5
contributors/michel-steuwer.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 3
|
||||
name: Michel Steuwer
|
||||
github: michel-steuwer
|
||||
---
|
5
contributors/mietek.metadata
Normal file
5
contributors/mietek.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Miëtek Bak
|
||||
github: mietek
|
||||
count: 1
|
||||
---
|
5
contributors/moleike.metadata
Normal file
5
contributors/moleike.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: Alexandre Moreno
|
||||
github: moleike
|
||||
---
|
5
contributors/momirza.metadata
Normal file
5
contributors/momirza.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 7
|
||||
name: Mo Mirza
|
||||
github: momirza
|
||||
---
|
5
contributors/mreed20.metadata
Normal file
5
contributors/mreed20.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 19
|
||||
name: Michael Reed
|
||||
github: mreed20
|
||||
---
|
5
contributors/murilogiacometti.metadata
Normal file
5
contributors/murilogiacometti.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 3
|
||||
name: Murilo Giacometti Rocha
|
||||
github: murilogiacometti
|
||||
---
|
5
contributors/nad.metadata
Normal file
5
contributors/nad.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Nils Anders Danielsson
|
||||
github: nad
|
||||
count: 1
|
||||
---
|
5
contributors/navaati.metadata
Normal file
5
contributors/navaati.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Léo Gillot-Lamure
|
||||
github: navaati
|
||||
---
|
5
contributors/nyraghu.metadata
Normal file
5
contributors/nyraghu.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: N. Raghavendra
|
||||
github: nyraghu
|
||||
count: 1
|
||||
---
|
5
contributors/odanoburu.metadata
Normal file
5
contributors/odanoburu.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 3
|
||||
name: bc²
|
||||
github: odanoburu
|
||||
---
|
5
contributors/omelkonian.metadata
Normal file
5
contributors/omelkonian.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 5
|
||||
name: Orestis Melkonian
|
||||
github: omelkonian
|
||||
---
|
5
contributors/pedrominicz.metadata
Normal file
5
contributors/pedrominicz.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 4
|
||||
name: Pedro Minicz
|
||||
github: pedrominicz
|
||||
---
|
5
contributors/peterthiemann.metadata
Normal file
5
contributors/peterthiemann.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: Peter Thiemann
|
||||
github: peterthiemann
|
||||
---
|
5
contributors/phi16.metadata
Normal file
5
contributors/phi16.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 4
|
||||
name: phi16
|
||||
github: phi16
|
||||
---
|
5
contributors/philderbeast.metadata
Normal file
5
contributors/philderbeast.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Phil de Joux
|
||||
github: philderbeast
|
||||
---
|
5
contributors/potato4444.metadata
Normal file
5
contributors/potato4444.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Nathaniel Carroll
|
||||
github: potato4444
|
||||
---
|
5
contributors/purchan.metadata
Normal file
5
contributors/purchan.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: purchan
|
||||
github: purchan
|
||||
---
|
5
contributors/qaisjp.metadata
Normal file
5
contributors/qaisjp.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 5
|
||||
name: Qais Patankar
|
||||
github: qaisjp
|
||||
---
|
5
contributors/rodamber.metadata
Normal file
5
contributors/rodamber.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Rodrigo Bernardo
|
||||
github: rodamber
|
||||
---
|
5
contributors/sabry.metadata
Normal file
5
contributors/sabry.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Amr Sabry
|
||||
github: sabry
|
||||
count: 1
|
||||
---
|
5
contributors/spwhitt.metadata
Normal file
5
contributors/spwhitt.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: Spencer Whitt
|
||||
github: spwhitt
|
||||
---
|
5
contributors/stepchowfun.metadata
Normal file
5
contributors/stepchowfun.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Stephan Boyer
|
||||
github: stepchowfun
|
||||
---
|
5
contributors/trajafri.metadata
Normal file
5
contributors/trajafri.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: Syed Turab Ali Jafri
|
||||
github: trajafri
|
||||
---
|
5
contributors/vikraman.metadata
Normal file
5
contributors/vikraman.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
name: Vikraman Choudhury
|
||||
github: vikraman
|
||||
count: 1
|
||||
---
|
5
contributors/vipo.metadata
Normal file
5
contributors/vipo.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Slava
|
||||
github: vipo
|
||||
---
|
5
contributors/whxvd.metadata
Normal file
5
contributors/whxvd.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 3
|
||||
name: Sebastian Miele
|
||||
github: whxvd
|
||||
---
|
5
contributors/ywata.metadata
Normal file
5
contributors/ywata.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 20
|
||||
name: Yasu Watanabe
|
||||
github: ywata
|
||||
---
|
5
contributors/zachrbrown.metadata
Normal file
5
contributors/zachrbrown.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 2
|
||||
name: Zach Brown
|
||||
github: zachrbrown
|
||||
---
|
5
contributors/zenzike.metadata
Normal file
5
contributors/zenzike.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Nicolas Wu
|
||||
github: zenzike
|
||||
---
|
5
contributors/zgrannan.metadata
Normal file
5
contributors/zgrannan.metadata
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
count: 1
|
||||
name: Zack Grannan
|
||||
github: zgrannan
|
||||
---
|
|
@ -81,7 +81,7 @@ Since we define equality here, any import would create a conflict.
|
|||
#### Exercise `≤-Reasoning` (stretch)
|
||||
|
||||
The proof of monotonicity from
|
||||
Chapter [Relations]({{ site.baseurl }}/Relations/)
|
||||
Chapter [Relations](/Relations/)
|
||||
can be written in a more readable form by using an analogue of our
|
||||
notation for `≡-Reasoning`. Define `≤-Reasoning` analogously, and use
|
||||
it to write out an alternative proof that addition is monotonic with
|
||||
|
@ -126,8 +126,8 @@ Show that equivalence is reflexive, symmetric, and transitive.
|
|||
#### Exercise `Bin-embedding` (stretch) {#Bin-embedding}
|
||||
|
||||
Recall that Exercises
|
||||
[Bin]({{ site.baseurl }}/Naturals/#Bin) and
|
||||
[Bin-laws]({{ site.baseurl }}/Induction/#Bin-laws)
|
||||
[Bin](/Naturals/#Bin) and
|
||||
[Bin-laws](/Induction/#Bin-laws)
|
||||
define a datatype `Bin` of bitstrings representing natural numbers,
|
||||
and asks you to define the following functions and predicates:
|
||||
|
||||
|
@ -149,7 +149,7 @@ Why do `to` and `from` not form an isomorphism?
|
|||
|
||||
#### Exercise `⇔≃×` (recommended)
|
||||
|
||||
Show that `A ⇔ B` as defined [earlier]({{ site.baseurl }}/Isomorphism/#iff)
|
||||
Show that `A ⇔ B` as defined [earlier](/Isomorphism/#iff)
|
||||
is isomorphic to `(A → B) × (B → A)`.
|
||||
|
||||
```
|
||||
|
@ -221,7 +221,7 @@ Does the converse hold? If so, prove; if not, give a counterexample.
|
|||
#### Exercise `<-irreflexive` (recommended)
|
||||
|
||||
Using negation, show that
|
||||
[strict inequality]({{ site.baseurl }}/Relations/#strict-inequality)
|
||||
[strict inequality](/Relations/#strict-inequality)
|
||||
is irreflexive, that is, `n < n` holds for no `n`.
|
||||
|
||||
```
|
||||
|
@ -232,7 +232,7 @@ is irreflexive, that is, `n < n` holds for no `n`.
|
|||
#### Exercise `trichotomy` (practice)
|
||||
|
||||
Show that strict inequality satisfies
|
||||
[trichotomy]({{ site.baseurl }}/Relations/#trichotomy),
|
||||
[trichotomy](/Relations/#trichotomy),
|
||||
that is, for any naturals `m` and `n` exactly one of the following holds:
|
||||
|
||||
* `m < n`
|
||||
|
@ -310,7 +310,7 @@ postulate
|
|||
(∀ (x : A) → B x × C x) ≃ (∀ (x : A) → B x) × (∀ (x : A) → C x)
|
||||
```
|
||||
Compare this with the result (`→-distrib-×`) in
|
||||
Chapter [Connectives]({{ site.baseurl }}/Connectives/).
|
||||
Chapter [Connectives](/Connectives/).
|
||||
|
||||
|
||||
#### Exercise `⊎∀-implies-∀⊎` (practice)
|
||||
|
@ -400,9 +400,9 @@ Does the converse hold? If so, prove; if not, explain why.
|
|||
#### Exercise `Bin-isomorphism` (stretch) {#Bin-isomorphism}
|
||||
|
||||
Recall that Exercises
|
||||
[Bin]({{ site.baseurl }}/Naturals/#Bin),
|
||||
[Bin-laws]({{ site.baseurl }}/Induction/#Bin-laws), and
|
||||
[Bin-predicates]({{ site.baseurl }}/Relations/#Bin-predicates)
|
||||
[Bin](/Naturals/#Bin),
|
||||
[Bin-laws](/Induction/#Bin-laws), and
|
||||
[Bin-predicates](/Relations/#Bin-predicates)
|
||||
define a datatype `Bin` of bitstrings representing natural numbers,
|
||||
and asks you to define the following functions and predicates:
|
||||
|
||||
|
@ -469,7 +469,7 @@ postulate
|
|||
#### Exercise `iff-erasure` (recommended)
|
||||
|
||||
Give analogues of the `_⇔_` operation from
|
||||
Chapter [Isomorphism]({{ site.baseurl }}/Isomorphism/#iff),
|
||||
Chapter [Isomorphism](/Isomorphism/#iff),
|
||||
operation on booleans and decidables, and also show the corresponding erasure:
|
||||
```
|
||||
postulate
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue