1-- The Lucas numbers 2, 1, 3, 4, 7, …: the same recurrence as the Fibonacci2-- numbers with the other start, their expression through Fibonacci numbers,3-- the doubling formula F(2n) = F(n) L(n), and the sum identity4-- Part of Cumulus, the Grace17 mathematics library.5-- Copyright (c) 2026 Grant Passmore.6-- Released under the Apache License 2.0. See LICENSE in the repository root.7-- Authors: Grant Passmore89module Grace.Cumulus.Combinatorics.Lucas10import Fibonacci1112def lucas (n : Nat) : Nat:= fibonacciAux(n, 2, 1)1314theorem lucas.zero15shows lucas(0) =216proof17compute1819theorem lucas.one20shows lucas(1) =121proof22compute2324theorem lucas.two25shows lucas(2) =326proof27compute2829theorem lucas.natural (n : Nat)30showsNat(lucas(n))31proof32unfold lucas33have twoNat : Nat(2) bytypecheck34have oneNat : Nat(1) bytypecheck35exact fibonacciAux.closed at n with2, twoNat, 1, oneNat3637theorem lucas.succ_succ (n : Nat)38shows lucas(n +2) = lucas(n) + lucas(n +1)39proof40unfold lucas41have twoNat : Nat(2) bytypecheck42have oneNat : Nat(1) bytypecheck43exact fibonacciAux.shift at n with2, twoNat, 1, oneNat4445-- L(n + 1) = F(n) + F(n + 2), proved together with its successor.46theorem lucas.fibonacci_pair (n : Nat)47shows lucas(n +1) = fibonacci(n) + fibonacci(n +2) ∧48 lucas(n +2) = fibonacci(n +1) + fibonacci(n +3)49proof50induction n51| zero =>52have one : 0+1=1bycompute53have two : 0+2=2bycompute54have three : 0+3=3bycompute55rw [one, two, three]56constructor57 . compute58 . compute59| k +1using ih =>60have first := ih.left61have second := ih.right62have shapeA : k +1+1= k +2byring63have shapeB : k +1+2= k +3byring64have shapeC : k +1+3= k +4byring65rw [shapeA, shapeB, shapeC]66constructor67 . exact second68 . have stepL := lucas.succ_succ at k +169rw [shapeB, shapeA] at stepL70have stepF := fibonacci.succ_succ at k71have stepF2 := fibonacci.succ_succ at k +272have shapeD : k +2+2= k +4byring73have shapeE : k +2+1= k +3byring74rw [shapeD, shapeE] at stepF275rw [stepL, first, second, stepF2, stepF]76have natK := fibonacci.natural at k77have natK1 := fibonacci.natural at k +178have natK3 := fibonacci.natural at k +379ring8081theorem lucas.fibonacci (n : Nat)82shows lucas(n +1) = fibonacci(n) + fibonacci(n +2)83proof84have pair := lucas.fibonacci_pair at n85exact pair.left8687theorem lucas.positive (n : Nat)88shows0 < lucas(n)89proof90havesplit:= natural.zero_or_successor at n91casessplitwith isZero | isSucc92 . rw [isZero, lucas.zero]93arith94 . obtain⟨k, kNat, shape⟩:= isSucc95have hk : succ(k) = k +196 symm97exact add.right_one at k98rw [shape, hk, lucas.fibonacci]99have positive := fibonacci.positive at k +1100have shape2 : k +1+1= k +2byring101rw shape2 at positive102have natK := fibonacci.natural at k103have natK2 := fibonacci.natural at k +2104arith105106-- The doubling formula F(2(n + 1)) = F(n + 1) · L(n + 1).107theorem fibonacci.double (n : Nat)108shows fibonacci(2* (n +1)) = fibonacci(n +1) * lucas(n +1)109proof110have shape : 2* (n +1) = (n +1) + n +1byring111rw [shape, fibonacci.add, lucas.fibonacci]112have shape2 : n +1+1= n +2byring113rw shape2114have natN := fibonacci.natural at n115have natN1 := fibonacci.natural at n +1116have natN2 := fibonacci.natural at n +2117ring118119-- L(n + 1) + L(n + 3) = 5 · F(n + 2).120theorem lucas.five_fibonacci (n : Nat)121shows lucas(n +1) + lucas(n +3) =5* fibonacci(n +2)122proof123have first := lucas.fibonacci at n124have third := lucas.fibonacci at n +2125have shapeA : n +2+1= n +3byring126have shapeB : n +2+2= n +4byring127rw [shapeA, shapeB] at third128rw [first, third]129have step0 := fibonacci.succ_succ at n130have step1 := fibonacci.succ_succ at n +1131have step2 := fibonacci.succ_succ at n +2132have shapeC : n +1+2= n +3byring133have shapeD : n +1+1= n +2byring134rw [shapeC, shapeD] at step1135rw [shapeB, shapeA] at step2136have natN := fibonacci.natural at n137have natN1 := fibonacci.natural at n +1138ring [step2, step1, step0]139140-- Partial sums of the Lucas numbers.141def lucasSum (n : Nat) →Nat142| zero =>0143| succ(k) => lucasSum(k) + lucas(k)144145theorem lucasSum.zero146shows lucasSum(0) =0147proof148compute149150theorem lucasSum.succ (k : Nat)151shows lucasSum(k +1) = lucasSum(k) + lucas(k)152proof153have one : k +1= succ(k) := add.right_one with*154rw one155simp [lucasSum]156157theorem lucasSum.natural (n : Nat)158showsNat(lucasSum(n))159proof160induction n161| zero =>162rw lucasSum.zero163typecheck164| k +1using ih =>165rw lucasSum.succ166have natK := lucas.natural at k167typecheck168169-- L(0) + ⋯ + L(n − 1) = L(n + 1) − 1.170theorem lucasSum.identity (n : Nat)171shows lucasSum(n) +1= lucas(n +1)172proof173induction n174| zero =>compute175| k +1using ih =>176have shape : k +1+1= k +2byring177rw [shape, lucas.succ_succ, lucasSum.succ, ← ih]178have natK := lucas.natural at k179have natSum := lucasSum.natural at k180ring181