Following up from a previous question here. I'm trying to extend my definition of an abstract power for all integers.
I thought I setup the triggers correctly but I'm still running into recursive triggers endlessly verifying. Is there a better way to debug recursive triggers than just guessing and checking? I basically sit there with task manager open seeing if z3 is eating all the memory. I hope there is a way to get better visibility about what is happening.
function apow<A>(g: Group, elem: A, n: int): A
decreases n*n
ensures n == 0 ==> apow(g,elem,n) == g.identity
{
if n == 0 then g.identity else if n > 0 then g.compose(elem, apow(g, elem, n-1)) else if n < 0 then g.compose(g.inverse(elem), apow(g, elem, n+1)) else g.identity
}
lemma apowClosed<A>(g: Group, elem: A, n: int)
requires elem in g.elements
requires g.identity in g.elements
requires isIdentity(g)
requires closedComposition(g)
requires closedInverse(g)
requires isInverse(g)
decreases n*n
ensures apow(g, elem, n) in g.elements
{}
lemma allApowClosed<A>(g: Group, elem: A)
requires ValidGroup(g)
requires elem in g.elements
ensures forall x: int :: apow(g, elem, x) in g.elements
{
reveal apow();
forall x: int {
apowClosed(g, elem, x);
}
}
lemma {:verify true} apowAdditionInt<A>(g: Group<A>, elem: A, n: int, k: int)
requires elem in g.elements
// requires ValidGroup(g)
requires closedComposition(g)
requires closedInverse(g)
requires g.identity in g.elements
requires isIdentity(g);
requires associativeComposition(g)
ensures g.compose(apow(g, elem, n), apow(g, elem, k)) == apow(g, elem, n+k)
{
allApowClosed(g, elem);
if k == 0 {
assert apow(g, elem, k) == g.identity;
assert g.compose(apow(g, elem, n), g.identity) == apow(g, elem, n+k);
}else if n == 0 {
assert apow(g, elem, n) == g.identity;
assert g.compose(g.identity, apow(g, elem, k)) == apow(g, elem, n+k);
}else if n > 0 && n+k > k {
apowPos(g, elem, n);
apowPos(g, elem, n+k);
assert apow(g, elem, n-1) in g.elements;
assert apow(g, elem, k) in g.elements;
assert apow(g, elem, n+k) in g.elements;
// assume g.compose(elem, g.compose(apow(g, elem, n-1), apow(g, elem, k))) == g.compose(elem, apow(g, elem, n-1+k));
calc {
g.compose(apow(g, elem, n), apow(g, elem, k));
g.compose(g.compose(elem, apow(g, elem, n-1)), apow(g, elem, k));
g.compose(elem, g.compose(apow(g, elem, n-1), apow(g, elem, k)));
== {apowAdditionInt(g,elem, n-1,k);}
g.compose(elem, apow(g, elem, n-1+k));
// apow(g, elem, n+k);
}
// }else{
}else{
}
}
datatype Group<!A> = Group(elements: set<A>, identity: A, compose: (A,A) -> A, inverse: (A) -> A)
predicate isIdentity<A>(g: Group<A>) {
forall a :: a in g.elements ==> g.compose(a,g.identity) == a && g.compose(g.identity, a) == a
}
predicate closedComposition<A>(g: Group<A>) {
forall x,y :: x in g.elements && y in g.elements ==> g.compose(x,y) in g.elements
}
predicate associativeComposition<A>(g: Group<A>) {
forall a,b,c :: a in g.elements && b in g.elements && c in g.elements ==> g.compose(g.compose(a,b),c) == g.compose(a, g.compose(b,c))
}
predicate closedInverse<A>(g: Group<A>) {
forall x {:trigger g.inverse(x)} :: x in g.elements ==> g.inverse(x) in g.elements
}
predicate isInverse<A>(g: Group<A>) {
forall x {:trigger g.inverse(x)} :: x in g.elements ==> g.compose(x,g.inverse(x)) == g.identity && g.compose(g.inverse(x),x) == g.identity
}
I'm using AGDA to do some classical mathematical proofs. I'd like to prove that the number of subsets of a set of cardinality n is equal to 2^n (i.e pow (2, n)). To do so, my strategy would be the following :
1) Write a function sub n, that, given each natural, it returns a list of all the possible subsets of naturals less or equal to n.
2) Write two functions "length " and "pow ", that separately compute the length of the list and 2^n
3) Put the 3 functions together to prove the statement.
However, I'm having troubles to solve point 1 ). My idea is to make the function return a list of type "list Nat", but I am having some problem to implement the recursion. Basically my idea for the inductive step is to associate to each subset of "n" two new subsets : itself and the subset obtained adding "n+1".
Do you think it is an effective strategy? And moreover, how can I solve my troubles with point 1?
Thanks
By the way, I have solved my problem using the strategy I proposed. To define the function that compute the number of subsets I use the standard map function and an additional auxiliary function add-to-list:
add-to-list : ℕ → List ℕ → List ℕ
add-to-list n x = n ∷ x
subℕ : ℕ → List ( List ℕ )
subℕ zero = [ 0 ] ∷ []
subℕ (suc x) = subℕ x ++ ( map ( add-to-list x ) ( subℕ x ) )
Then, I prove the two following elementary lemmas:
l-aux : ∀ {A : Set } { x y : List A } → ( length ( x ++ y ) )≡( ( length x ) + ( length y ))
l-aux {A} {[]} {y} = refl
l-aux {A} {x ∷ x₁} {y} rewrite l-aux {A} { x₁} {y} = refl
l-aux-1 : ∀ {A : Set } { x : List A } { f : A → A } → ( length ( map f x ) ) ≡ ( length x )
l-aux-1 {A} {[]} {f} = refl
l-aux-1 {A} {x ∷ x₁} {f} rewrite l-aux-1 {A} { x₁} {f} = refl
And the proof is reduced to elementary recursion :
number-of-subsets : ∀ ( n : ℕ ) → ( length ( subℕ n ) ) ≡ ( pow 2 n )
number-of-subsets zero = refl
number-of-subsets (suc n ) rewrite l-aux {List ℕ} {subℕ n} { map ( add-to-list n ) (subℕ n)} | l-aux-1 {List ℕ} {subℕ n} {add-to-list n } | number-of-subsets n | +0 (pow 2 n ) = refl
How would I go about applying a function n-times in OCaml if I don't
know the functions argument?
I want the call iter(n, fun x -> 2+x) 0 to evaluate to 2*n since
that would be the same as 2+2+2+2.... Also, if n=0 it should
return the identity function.
My attempt:
let rec iter : int * (int -> int) -> (int -> int)
= fun (n,f) ->
if n = 0 then f
else iter((n-1), f( f () ))
Possible duplicate: OCaml recursive function to apply a function n times but this question has an argument for the anonymous function so the answers does not help me.
You may not “have an argument” right now, but since the result is a function you can always just bring an argument in scope by returning a lambda:
let rec iter : int * (int -> int) -> (int -> int)
= fun (n,f) ->
if n = 0 then f
else fun x -> iter(n-1, f) (f x);;
Try it online!
Note that, as Willem remarks, your base case is probably wrong: for n=0, you want to return the identity function regardless of what function is passed in. Otherwise you get strange behaviour, for instance such a function should generally fulfill iter (n, fun x -> x+1) 0 ≡ n, but with your base case it gives n+1.
I would write the function thus:
let rec iter : int -> ('a -> 'a) -> ('a -> 'a)
= fun n f x -> if n = 0
then x
else iter (n-1) f (f x);;
Try it online!
Here I've not explicitly mentioned the identity function, but because I just return x when n is zero, that's what the identity function does. Alternatively, you can return another lambda which just passes the argument through:
let rec iter : int -> ('a -> 'a) -> 'a -> 'a
= fun n f ->
if n = 0
then fun x -> x (* identity function *)
else fun x -> iter (n-1) f (f x);;
I am not really sure if this is what you want - a small modification of the answer you linked to seems to do the job though:
*Edit: identity function depends on the nature of the function you pass to iter (right?), so I am not really sure how you can get it just from looking at f. That's why I am only returning f for now. And repeat fun x -> x + 2 n times - wouldn't that give you x + 2 * n?
let iter n f =
let chain_func f1 f2 arg = f1 (f2 arg) in
let rec aux n f newf =
if n <= 0 then newf else aux (n - 1) f ( chain_func f newf ) in
aux (n - 1) f f;;
*Edit 2: identity function is fun x -> x so the last line needs to be fixed to: aux n f (fun x -> x)
How to use a (hypothetical) routine integral( f ) which computes the integral of function f over [0,1] to compute the integral of f over any interval [a,b]?
If I wanted to change the interval of integration I would use the following substitution:
y = (x-a)/(b-a)
dy = (1/(b-a))dx
Which means that I can now compute the integral f(y)*(b-a)dy over [0,1] to get the same result I would get from integrating f(x)dx over [a,b], however the funtion integral() takes one argument - a function - and I'm having a hard time figuring out how to use the substitution I've found to derive that function.
You create a new function, g, which is an appropriately scaled version of the original function f.
g(x) = f(a + x * (b - a))
// Now we have ...
// g(0) = f(a)
// g(1) = f(b)
// ... and the function between is linearly scaled
Then you pass this function to integral. The result needs to be scaled (since the step has also been scaled) by (b - a).
So far for the theory, but in practice you can only do this when you can create closures, that is functions with some data from their (lexical) environment to close over. (Or if you have some way to emulate that, like an additional void * user_data parameter as used in some C libraries)
Also, since you tagged this with numerical-integration, you need to consider that the step size used by integral could be appropriate for many functions, but the scaled step size could be to large for integration to yield correct results.
Small example in Common Lisp:
;; from http://rosettacode.org/wiki/Numerical_integration#Common_Lisp
(defun left-rectangle (f a b n &aux (d (/ (- b a) n)))
(* d (loop for x from a below b by d summing (funcall f x))))
(defun integral (f)
(left-rectangle f 0 1 10))
(defun integral-range (f a b)
(* (- b a) (integral #'(lambda (x) (funcall f (float (+ a (* x (- b a)))))))))
(defun test-fn (x) (* x 2))
(trace test-fn)
(let ((i (integral-range #'test-fn 3 9)))
(format t "Result of numerical integration: ~a~%" i)
(format t "Error of numerical integration: ~a~%" (abs (- i (- (* 9 9) (* 3 3))))))
You can see it in action, where the "Trace" output shows at which points the test function is evaluated.
And here a C version, emulating the mentioned closure by assigning global static variables:
#include <stdio.h>
#include <math.h>
// from http://rosettacode.org/wiki/Numerical_integration#C
double int_leftrect(double from, double to, double n, double (*func)())
{
double h = (to-from)/n;
double sum = 0.0, x;
for(x=from; x <= (to-h); x += h)
sum += func(x);
return h*sum;
}
double integral(double (*func)()) {
return int_leftrect(0, 1, 10, func);
}
static double from;
static double to;
static double (*fn)();
double scaled(double x) {
return fn(from + x * (to - from));
}
double integral_range(double (*func)(), double a, double b) {
from = a;
to = b;
fn = func;
return integral(scaled) * (b - a);
}
double test_fn(double x) {
double result = 2 * x;
printf("TRACE: test_fn(%f) => %f\n", x, result);
return result;
}
int main(void) {
double result = integral_range(test_fn, 3, 9);
double expected = (9 * 9) - (3 * 3);
printf("result of numerical integration: %f\n", result);
printf("error of numerical integration: %f\n", fabs(result - expected));
return 0;
}
(In action)
I solve it by php,and it works.but I try to use scheme,I receive the " Aborting!: maximum recursion depth exceeded" error. I use MIT/GNU Scheme microcode 15.3
.Here is the code.
php
function cc($a,$b)
{
if($b==1){
return $a;
}elseif($b%2!==0){
return $a+cc($a,$b-1);
}else{
return cc(double1($a),halve($b));
}
}
function double1($i)
{
return 2*$i;
}
function halve($i)
{
return $i/2;
}
scheme
(define (cc a b)
(cond ((= b 1) a))
((odd? b) (+ a (cc a (- b 1))))
(else (cc (double a) (halve b)))
)
(define (double n)
(+ n n)
)
(define (halve n)
(/ n 2)
)
Your Scheme version isn't quite correct. It's more like this PHP version:
function cc($a, $b){
if ($b === 1) { return $a; }
call_user_func($b%2!==0,
$a + cc($a, $b-1) );
return else(cc(double1($a), halve($b)) );
}
Perhaps this is a better version:
(define (cc a b)
(cond ((= b 1) a)
((odd? b) (+ a (cc a (- b 1))))
(else (cc (double a) (halve b)))))
Notice the identation reflects the move of ) from the first line of cond to the very last.