summaryrefslogtreecommitdiff
path: root/assignment7/E.pvs
diff options
context:
space:
mode:
Diffstat (limited to 'assignment7/E.pvs')
-rw-r--r--assignment7/E.pvs109
1 files changed, 109 insertions, 0 deletions
diff --git a/assignment7/E.pvs b/assignment7/E.pvs
new file mode 100644
index 0000000..5f02082
--- /dev/null
+++ b/assignment7/E.pvs
@@ -0,0 +1,109 @@
+%%% NAME/LOGIN-ID Camil Staps / s4498062
+%%% ACKNOWLEDGMENTS:
+
+th_E: THEORY
+
+BEGIN
+
+%%%
+%%% Standard development of iterative factorial-with-accumulator.
+%%% Start with a "specification" of the factorial function.
+%%%
+
+fac(n:nat): RECURSIVE nat =
+ IF n = 0
+ THEN 1
+ ELSE fac(n-1) * n
+ ENDIF
+ MEASURE n
+
+%%%
+%%% A few simple facts about the factorial function.
+%%%
+
+thm_E_0: LEMMA (FORALL (k:nat): k>=1 IMPLIES fac(k) < fac(k+1))
+
+thm_E_1: THEOREM (FORALL (k:nat): 1 <= fac(k))
+thm_E_2: THEOREM (FORALL (k:nat): k <= fac(k))
+
+%%%
+%%% In tfac, below, all recursive calls are in the tail position. In operational terms,
+%%% tfac "improves" fac because a no space is needed for a recursion stack. In other
+%%% words, tfac is and instance of the "implementation model" for sequential execution.
+%%%
+
+tfac(n:nat, m:nat): RECURSIVE nat =
+ IF n = 0
+ THEN m
+ ELSE tfac(n - 1, m * n)
+ ENDIF
+ MEASURE n
+
+%%%
+%%% We should prove, though, that tfac is equivalent to fac. They are not "equal" because,
+%%% for one thing, tfac takes two arguments and fac takes only one. In fact, tfac(n, m)
+%%% only computes fac(n) when m = 1.
+%%%
+%%% However, in trying to prove this, we run into a problem...
+%%% In the inductive case, we'll get something like this:
+%%%
+%%% [-1] fac(J) = tfac(J, 1)
+%%% |------------------------
+%%% [1] (J+1) * fac(J) = tfac(J, J+1)
+%%%
+%%% To complete the proof, we need to "distribute" J+1 outside fact. But attempting
+%%% to prove this, for just "J+1" will fail. A _generalization_ is needed...
+%%%
+
+lemma_E_3: LEMMA (FORALL (m:nat, n:nat): tfac(m, n) = n * fac(m))
+
+%%%
+%%% On the strength of this lemma, we can prove the correctness of tfac.
+
+th_E_4: THEOREM (FORALL (k:nat): fac(k) = tfac(k, 1))
+
+%%%
+%%% Below, we'll do the same standard development for iterative the Fibonacci function.
+%%% Except this time, YOU have to find the appropriate lemma! Although there are several
+%%% reasonable possibilities for the needed lemma, it is not easy to think of one.
+%%%
+%%% Remember that the lemma must GENERALIZE the desired result.
+%%%
+
+fib(n:nat): RECURSIVE nat =
+ (IF n = 0 THEN 1
+ ELSIF n = 1 THEN 1
+ ELSE fib(n - 1) + fib(n - 2)
+ ENDIF)
+ MEASURE n
+
+%%%
+%%% Tail-recursive version of fib.
+%%%
+
+tfib(n:nat, m:nat, p:nat): RECURSIVE nat =
+ (IF n = 0
+ THEN m
+ ELSE tfib(n - 1, p, p + m)
+ ENDIF)
+ MEASURE n
+
+%%%
+%%% YOU will need to discover a nontrivial lemma to prove thm.
+%%% Place your lemma just below, before thm_E_6.
+%%%
+
+lem_E_Camil_2: LEMMA
+ (FORALL (i:nat, m:nat, p:nat):
+ tfib(i, m, p) =
+ IF i = 0 THEN m
+ ELSIF i = 1 THEN p
+ ELSE fib(i-2)*m + fib(i-1)*p
+ ENDIF)
+
+thm_E_6: THEOREM
+ (FORALL (i:nat):
+ tfib(i, 1, 1) = fib(i))
+
+END th_E
+