lecture_2: THEORY BEGIN n, m: VAR nat f: VAR [nat -> nat] % Fun with summation sum(n): RECURSIVE nat = IF n = 0 THEN 0 ELSE n + sum(n - 1) ENDIF MEASURE n closed_form: THEOREM sum(n) = (n * (n + 1)) / 2 closed_form_bis: THEOREM sum(n) = (n * (n + 1)) / 2 % Induction-free induction factorial(n:nat) : RECURSIVE posnat = IF n = 0 THEN 1 ELSE n*factorial(n-1) ENDIF MEASURE n % fact_it(n:nat,i:upto(n),a:nat) : RECURSIVE nat = % IF i = n THEN a % ELSE fact_it(n,i+1,a*(i+1)) % ENDIF % MEASURE n-i fact_it(n:nat,i:upto(n),(a:posnat|a=factorial(i))) : RECURSIVE {b:posnat | b=factorial(n)} = IF i = n THEN a ELSE fact_it(n,i+1,a*(i+1)) ENDIF MEASURE n-i fact_it_correctness : THEOREM fact_it(n,0,1) = factorial(n) fact_it2(n:nat,i:upto(n),a:posnat) : RECURSIVE {b:posnat | b=a*factorial(n)/factorial(i)} = IF i = n THEN a ELSE fact_it2(n,i+1,a*(i+1)) ENDIF MEASURE n-i fact_it2_correctness : LEMMA fact_it2(n,0,1) = factorial(n) % Recursive judgments ack(m,n) : RECURSIVE nat = IF m = 0 THEN n+1 ELSIF n = 0 THEN ack(m-1,1) ELSE ack(m-1,ack(m,n-1)) ENDIF MEASURE lex2(m,n) ack_gt_m_n : RECURSIVE JUDGEMENT ack(m,n) HAS_TYPE above(m+n) ack_simple_property : THEOREM FORALL(m,n): ack(m,n) > max(m,n) % For loops % /* Pre: n >= 0 */ % int a = 1; % for (int i=0;i < n;i++) { % /* Inv: a = i! */ % a = a*(i+1); % } % /* Post: a = n! */ IMPORTING structures@for_iterate fact_for(n:nat) : real = for[real](0,n-1,1,LAMBDA(i:below(n),a:real): a*(i+1)) fact_for : THEOREM fact_for(n) = factorial(n) % Example inductive definitions % Sample inductive definitions, use M-x ppe to see automatically % generated induction schemas even(n:nat): INDUCTIVE bool = n = 0 OR (n > 1 AND even(n - 2)) odd(n:nat): INDUCTIVE bool = n = 1 OR (n > 1 AND odd(n - 2)) % use (rule-induct "even") even_odd: LEMMA even(n) => odd(n + 1) % use (rule-induct "odd") odd_even: LEMMA odd(n) => even(n + 1) % use (induct-and-simplify "n") % then use the preceding two lemmas even_or_odd: LEMMA even(n) OR odd(n) %% PVS DOES NOT (DIRECTLY) SUPPORT MUTUAL RECURSION % my_even?(n) : INDUCTIVE bool = % n = 0 OR n > 0 AND my_odd?(n-1) % % my_odd?(n) : INDUCTIVE bool = % n = 1 OR n > 1 AND my_even?(n-1) %% Mutual recursion can be simulated using regular recursion even_f?(fodd:[nat->bool],n) : bool = n = 0 OR n > 0 AND fodd(n-1) my_odd?(n) : INDUCTIVE bool = n = 1 OR n > 1 AND even_f?(my_odd?,n-1) my_even?(n) : bool = even_f?(my_odd?,n) % Fun with trees Tree : DATATYPE BEGIN nulltree : nulltree? constree(val:nat,left:Tree,right:Tree) : constree? END Tree height(t:Tree) : RECURSIVE nat = CASES t OF constree(v,l,r): 1+max(height(l),height(r)) ELSE 0 ENDCASES MEASURE t BY << monotonetree?(t:Tree): INDUCTIVE bool = nulltree?(t) OR (constree?(left(t)) IMPLIES val(t) > val(left(t))) AND (constree?(right(t)) IMPLIES val(t) > val(right(t))) AND monotonetree?(left(t)) AND monotonetree?(right(t)) consotonetree?(t:Tree): MACRO bool = constree?(t) AND monotonetree?(t) END lecture_2