%% Totality of Euclid's GCD algorithm
%% This requires strong induction which we can encode using regular
%% inducution together with an ordering on natural numbers.
%%
%% Adapted from the %reduces example in the Twelf User's Guide:
%% http://www.cs.cmu.edu/~twelf/guide-1-4/twelf_8.html#SEC47
Specification "gcd".
Theorem sub_total_tt : forall X Y,
{less X Y tt} -> exists Z, {sub Y X Z}.
induction on 1. intros. case H1.
search.
apply IH to H2. search.
Theorem sub_total_ff : forall X Y,
{less X Y ff} -> exists Z, {sub X Y Z}.
induction on 1. intros. case H1.
search.
apply IH to H2. search.
Theorem less_total : forall X Y,
{nat X} -> {nat Y} -> exists B, {bool B} /\ {less X Y B}.
induction on 1. intros. case H1.
case H2.
search.
search.
case H2.
search.
apply IH to H3 H4. search.
Theorem lt_trans : forall X Y Z,
{lt X (s Y)} -> {lt Y Z} -> {lt X Z}.
induction on 1. intros. case H1.
case H2.
search.
search.
case H2.
case H3.
apply IH to H3 H4. search.
Theorem lt_nat : forall X Y,
{lt X Y} -> {nat X}.
induction on 1. intros. case H1.
search.
apply IH to H2. search.
Theorem lt_x_sx : forall X,
{nat X} -> {lt X (s X)}.
induction on 1. intros. case H1.
search.
apply IH to H2. search.
Theorem lt_s : forall X Y,
{lt X Y} -> {lt X (s Y)}.
induction on 1. intros. case H1.
search.
apply IH to H2. search.
Theorem sub_lt : forall X Y Z,
{nat X} -> {sub X Y Z} -> {lt Z (s X)}.
induction on 2. intros. case H2.
apply lt_x_sx to H1. search.
case H1. apply IH to H4 H3. apply lt_s to H5. search.
Theorem gcd_total_strong : forall A B,
{nat A} -> {nat B} ->
(forall X Y, {lt X A} -> {lt Y B} -> exists Z, {nat Z} /\ {gcd X Y Z}).
induction on 1. induction on 2. intros.
apply lt_nat to H3. apply lt_nat to H4.
% Trivial base cases
case H1 (keep). case H3.
case H2 (keep). case H4.
% A = s N, B = s N1
apply IH to H7 H2. apply IH1 to H1 H8.
clear IH IH1 H1 H2 H7 H8.
% X = z
case H3. search.
% Y = z
case H4. search.
% X = s X1, Y = s X2
case H5. case H6.
apply less_total to H13 H14. case H15.
% X1 < X2
apply sub_total_tt to H16.
apply sub_lt to H14 H17.
apply lt_trans to H18 H12.
apply H10 to _ H19 with X = s X1. search.
% X1 >= X2
apply sub_total_ff to H16.
apply sub_lt to H13 H17.
apply lt_trans to H18 H11.
apply H9 to H19 _ with Y = s X2. search.
Theorem gcd_total : forall X Y,
{nat X} -> {nat Y} -> exists Z, {nat Z} /\ {gcd X Y Z}.
intros. assert {nat (s X)}. assert {nat (s Y)}.
apply gcd_total_strong to H3 H4.
apply lt_x_sx to H1. apply lt_x_sx to H2.
apply H5 to H6 H7. search.