June 29, 2020
Our thanks goes to:
Fabian Kunze and Simon Hudon for participating in the problem selection.
Fabian Kunze for doing all translations to Coq.
Simon Hudon and Kevin Kappelmann for translating the problems to Lean.
Jonas Bayer, Manuel Eberl, Martin Raszyk, Daniel Ricketts, and Christoph Walther for submitting problems.
Github repository with solutions: https://github.com/maxhaslbeck/proofground2020-solutions
Send us a pull request with your own!
Submitted by: Daniel Ricketts
This problem comes from a note called "Teaching Concurrency" by Leslie Lamport. In this problem, there are N processes and two arrays of length N, x and y. Each process i executes the following sequence of statements: x[i] := 1; y[i] := x[(i-1) mod N]; The reads and writes of each x[j] are assumed to be atomic. This algorithm has the property that once all processes have finished, at least one y[j] = 1. I've written proofs of this property in a few different proof systems, including Coq: https://github.com/dricketts/teaching-concurrency/blob/master/coq.v. That github repository contains solutions in other systems.
definition indinv where "indinv st ≡ safe st ∧ (∀i. Proc i ⟶ (pc st i = assign_y ∨ pc st i = finished) ⟶ x st i = 1)" lemma Proc_mod : "∀ i. Proc i ⟶ Proc ((i + 1) mod N)" unfolding Proc_def by auto lemma reachable_indinv : "indinv st" if "reachable st" using that proof induction case (init init_x init_y) then show ?case using proc_0 by (auto simp: indinv_def safe_def) next case (x_step st i) then show ?case by (auto simp: indinv_def safe_def update_x_def update_pc_def) next case (y_step st i) then show ?case apply (auto simp: indinv_def safe_def update_y_def update_pc_def) apply (metis Proc_mod Suc_eq_plus1)+ done qed theorem reachable_safe : "safe st" if "reachable st" using reachable_indinv[OF that] unfolding indinv_def ..
Submitted by: Manuel Eberl
Submitted by: Christoph Walther
Proving the infinitude of primes by pronic numbers. Prove that (Thm 1) ∀ n : N P(pf(S(n)+1)) (Thm 2) ∀ n, m : N pf(S(n)+1) = pf(S(m)+1) → n = m holds, where - N denotes the non-negative integers, - S : N → N is a mapping satisfying S(0) ≥ 2 and S(n + 1) := S(n) * (S(n) + 1), - P(n) denotes that n is prime, and - pf(n) stands for the smallest prime factor of n, provided n ≥ 2.
Main approach for (Thm 2):
n: 0 | 1 | 2 | 3 S(n): 2 | 6 | 42 | 1806 = 42 * 43 S(n)+1: 3 | 7 | 43 | 1807 pf(S(n)+1): 3 | 7 | 43 | 13 (13 * 139 = 1807)
S(m) + 1 | S(n) if m < n
Main approach for (Thm 2):
Submitted by: Martin Raszyk
Originally, checker code for an ACM problem.
Only two complete solutions, one Coq, one Isabelle.
theory Submission imports "HOL-Library.Sublist" Defs begin definition all_subseq :: "'a list ⇒ 'a list ⇒ bool" where "all_subseq xs ys ⟷ (∀xs'. xs' ⊑ xs ⟶ xs' ⊑ ys)" lemma subseq_id: "subseq = Sublist.subseq" apply (intro ext) apply safe subgoal premises prems using prems by induction auto subgoal premises prems using prems by induction auto done lemma proper_subseq_id: "proper_subseq = strict_subseq" unfolding proper_subseq_def strict_subseq_def subseq_id .. lemmas subseq_ids = subseq_id proper_subseq_id lemmas [termination_simp] = length_dropWhile_le lemma subseq_empty_iff: "xs ⊑  ⟷ xs = " unfolding subseq_ids by auto lemma [simp]: "all_subseq  ys ⟷ True" "all_subseq (x # xs)  ⟷ False" unfolding all_subseq_def by (auto simp: subseq_empty_iff) lemma [simp]: "all_subseq (x # xs) (y # ys) ⟷ all_subseq (x # xs) ys" if "x ≠ y" using that by (auto simp: all_subseq_def subseq_ids) lemma [simp]: "all_subseq (x # xs) (x # ys) ⟷ all_subseq xs ys" apply (auto simp: all_subseq_def subseq_ids) by (meson subseq_Cons2 subseq_order.dual_order.trans subseq_order.order_refl) lemma aux_correct: "aux xs ys ⟷ all_subseq xs ys" by (induction rule: aux.induct; simp) lemma strict_subseq_ConsE: assumes "a # as ⊏ bs" obtains xs ys where "bs = xs @ a # ys" "xs ≠ " "as ⊑ ys" | ys where "bs = a # ys" "as ⊏ ys" by (metis (full_types) assms list_emb_ConsD self_append_conv2 subseq_order.antisym_conv2 subseq_order.dual_order.strict_implies_order subseq_ids) lemma strict_subseqE: assumes "xs ⊏ ys" obtains as x bs where "ys = as @ x # bs" and "xs ⊑ as @ bs" using assms unfolding subseq_ids apply (induction xs arbitrary: ys) subgoal for ys apply (cases ys; force) done apply (erule strict_subseq_ConsE[unfolded subseq_ids]) apply (metis append_Cons append_Nil list.exhaust list_emb_append2 subseq_Cons2_iff) by (metis append.simps(2) subseq_Cons2) lemma all_proper_subseq_subdivide: "all_proper_subseq xs ys ⟷ (∀as x bs. xs = as @ x # bs ⟶ all_subseq (as @ bs) ys)" unfolding all_proper_subseq_def all_subseq_def subseq_ids apply auto apply (meson list_emb_Cons not_Cons_self2 same_append_eq subseq_append_iff subseq_order.dual_order.order_iff_strict subseq_order.le_less_trans) subgoal by (erule strict_subseqE[unfolded subseq_ids]) auto done lemma aux2_iff: "aux2 ys acc xs ⟷ (∀as x bs. xs = as @ x # bs ⟶ aux (acc @ as @ bs) ys)" apply (induction xs arbitrary: acc) apply auto subgoal by (smt Nil_is_append_conv append_eq_append_conv2 hd_Cons_tl hd_append2 list.sel(1) list.sel(3) tl_append2) apply force by (metis append_Cons) lemma aux2_correct: "aux2 ys  xs ⟷ all_proper_subseq xs ys" unfolding aux2_iff all_proper_subseq_subdivide aux_correct by simp theorem judge1_correct: "judge1 xs ys ⟷ all_proper_subseq xs ys" unfolding judge1_def aux2_correct by auto definition "judge2 xs ys ⟷ judge1 xs ys" theorem judge2_correct: "judge2 xs ys ⟷ all_proper_subseq xs ys" unfolding judge2_def by (rule judge1_correct) theorem judge2_is_executable: "judge2 ''ab'' ''ab'' ⟷ True" "judge2 ''ba'' ''ab'' ⟷ True" "judge2 ''abcd'' ''cdabc'' ⟷ False" by eval+
Submitted by: Simon Wimmer
We expected this to be harder than
But got many good solutions.
Unfortunately, the Lean task was incorrect.