Map function in "Haskell like" language using folr - functional-programming

I'm trying to write a map function in a Haskell-like language. The operation I'm trying to use is a fold_right. So basically writing a map using foldr. However, I get a "parameter mismatch error".
Thank you.
map = lambda X. lambda Y.
lambda f: X -> Y.
lambda l: List X.
l [X] (
lambda hd:X.
lambda tl: List Y.
(cons[Y](f hd))(tl)
) (nil [Y]);

The first argument to l should be the type of the result of the fold (at least, that's my educated guess), the "motive". You want the end result to be a List Y, not an X, so you should say that:
map =
lambda X. lambda Y. lambda f: X -> Y. lambda l: List X.
l
[List Y]
(lambda x: X. lambda rec_xs: List Y. cons [Y] (f x) rec_xs)
(nil [Y]);
Maybe you got confused and wrote X because l is a List X? l already knows that it contains Xs; you don't need to point it out again. You just need to point out what you want get out (which could be X, but it isn't in this case).

Related

having difficulties analyzing recursive steps of a function

I'm currently studying OCaml for a functional programming exam and I'm having some difficulties trying to follow the steps of this recursive function in this exercise. The task is to find the most expensive leaf in a int N-ary tree (a leaf cost is given by the sum of integers on the path to a leaf).
This is the type definition:
type 'a ntree = Ntree of 'a * 'a ntree list
this is an auxiliary function for the exercise
let rec maxpair = function
| [] -> failwith "empty list"
| [(x, y)] -> (x, y)
| (x, y) :: (a, b) :: rest ->
if y > b then maxpair ((x, y) :: rest)
else maxpair ((a, b) :: rest)
and finally here's the final function
let rec leaf_cost = function
| Ntree (x, []) -> (x, x)
| Ntree (x, tlist) ->
let (y, c) = maxpair (List.map leaf_cost tlist)
in
(y, c + x)
This is the solution of the exercise, meaning it works. But I'm having trouble trying to analyze every recursive step in the function, especially because I'm a bit confused about the let (y, c) ... in (y, c + x) declaration.
Given a tree, leaf_cost returns a pair (v, c) which is the value of the leaf node with the maximal cost v, and that cost c.
In the base case, when there is no child node, the value is x and its cost is also x.
In the general case, a node is made of an integer x and list of child node children (aka tlist).
List.map leaf_cost children
The above expression is a list of pairs, each one being the maximum leaf and its associated cost in the respective subtree rooted in each child node.
In general, there might be multiple leaves with the same cost, but your problem ignores that and selects, in an implementation-defined way, a pair with the maximal cost among all costs so far.
This is done by calling maxpair, which gives a pair (y, c) where y is the first leaf having the maximal cost c among all the pairs obtained recursively.
Knowing that among all subtrees, (y, c) is a leaf with cost c, and that your current node weights x, the cost of the current node is c + x. That's why the returned value in the general case is (y, c+x), keeping track of the leaf in the subtrees that lead to this cost.

How do I define exchange(X) to make this theorem without error?

I am learning to use Isabelle to prove certain theories, but I encountered a problem. I would like to know how can I define exchange(X) to ensure that the theorem presented in the code listing below can be stated without causing an error?
theorem exchange_wp2_1:
"
preOrder(T) =X # preOrder(q) # F(S) ∧ exchange(X) ∧ q ≠ null ⟹
preOrder(T)=X # (data q) # preOrder(ltree q) # F ([rtree q] # S)
"
Error:
Type unification failed:Cash of types "_list" and "_tree" Type error
in application:incompatible operand type Operator: exchange::??
'tree⇒bool Operator: X::?? 'b list
I don't know exactly the definitions of preOrder and exchange, but it seems that preOrder returns a list, whereas exchange expects a tree as input. So, in your expression, it is unclear what type X should have: is it a tree or a list?
preOrder(T) = X (so X is list)
exchange X (so X is a tree)
this is what the error message tells you.

How to describe the one-many relations in Coq?

I was reading the book Introduction to Mathematical Philosophy by B.Russell and trying to formalize all the theorems described in it.
One-many relations are described by the following text (contexts on book).
One-many relations may be defined as relations such that, if x has the
relation in question to y, there is no other term x' which also has
the relation to y.
Or, again, they may be defined as follows: Given
two terms x and x', the terms to which x has the given relation and
those to which x' has it have no member in common.
Or, again, they may
be defined as relations such that the relative product of one of them
and its converse implies identity, where the “relative product” of two
relations R and S is that relation which holds between x and z when
there is an intermediate term y, such that x has the relation R to y
and y has the relation S to z.
It poses three ways of definition. I've been successfully described the first two and proved their equivalence. While I was stuck on the third, I tried to get rid of the concepts of 'relative product' and directly get to its connotation but also failed.
Here below are my definitions, did I make any mistakes?
Definition one_many {X} (R : relation X) : Prop :=
forall x y, R x y -> forall x', x <> x' -> ~(R x' y).
Definition one_many' {X} (R : relation X) : Prop :=
forall x x' y, R x y -> R x' y -> x = x'.
Inductive relative_product
{X} (R: relation X) (S: relation X) : relation X :=
| rp0 : forall x y, forall z, R x y -> S y z -> relative_product R S x z.
Inductive converse {X} (R : relation X) : relation X :=
| cv0 : forall x y, R x y -> converse R y x.
Inductive id {X} : relation X :=
| id0 : forall x, id x x.
Definition one_many'' {X} (R : relation X) : Prop :=
forall x y, relative_product R (converse R) x y <-> id x y.
Below is how I interpret the definition of the third and also I failed to prove their equivalence.
Goal forall {X} (R : relation X),
one_many'' R <-> (forall x y, R x y -> forall x', converse R y x' -> x = x').
Proof.
intros. unfold one_many''. split.
intros.
assert (relative_product R (converse R) x x' <-> id x x'). apply H.
inversion H2. apply id_eqv. apply H3.
apply rp0 with y. assumption. assumption.
intros.
split. intro.
inversion H0. subst.
apply id_eqv. apply H with y0.
assumption. assumption.
(* I'm stuck here. This subgoal is obviously not provable. *)
in which proof, id_eqv is Lemma id_eqv : forall {X} (x:X) (y:X), x = y <-> id x y, easily proved in advance.
Can somebody help me to figure out or give me a hint about where I went wrong? Thanks in advance.
I think you've mistranslated the third definition. The original text says:
Or, again, they may be defined as relations such that the relative product of one of them and its converse implies identity
(emphasis mine). That would translate as:
forall x y, relative_product R (converse R) x y -> id x y
That is, it should be a straight implication, rather than the equivalence you've asserted. You can't hope to prove your third statement from either of the others, since it's not equivalent: consider the empty relation on a nonempty set. That's certainly a one-to-many relation, but the relative product with its converse is also empty, so is not the full identity relation.
Wild guess, but you might need R to be reflexive or not empty. Using your script I end up having to prove
1 subgoal
X : Type
R : relation X
H : forall x y : X, R x y -> forall x' : X, converse R y x' -> x = x'
y : X
______________________________________(1/1)
relative_product R (converse R) y y
So you have a relation R, and one inhabitant y:X. To prove your goal, you need to have a witness z such that R y z and R z y. Without any other information, I guess your only shot is to have R to be reflexive and z be y.

Trouble with Curry functions (SML/NJ)

Often we are interested in computing f(i) i=m n∑ , the sum of function
values f(i) for i = m through n. Define ‘sigma f m n’ which computes
f(i) i=m n∑ . This is different from defining ‘sigma (f, m, n)’
I'm required to write a Curried version of this function. I'm have a bit of trouble understanding how this would actually work. I understand that a Curry function is something that takes in a function and produces a function. Would this be an example of a curry function?
fun myCurry f x = f(x)
As far as setting up my problem, would this be an acceptable start?
fun sigma f m n =
I haven't gotten any further, because I can't really grasp what i'm being asked to do.
A curried function is not, in fact, a function that takes in a function and produces another function. That is a higher order function.
A curried function is simply one that takes more than one argument and can be partially applied by only giving it one of its arguments.
For example, with your sigma question,
fun sigma (f,m,n) = ...
is not a curried function, as it takes only one argument (the tuple (f,m,n).)
fun sigma f m n = ...
, however, is a curried function, as it takes three arguments, and it is valid to say something like
val sigmasquare = sigma (fn x => x * x)
, partially applying sigma by giving it its first argument.
A simpler example would be
fun add (x,y) = x + y
This is a noncurried function. To evaluate it, you must give it its argument, which includes both x and y. add (3,5) will evaluate to 8, in this case.
fun add x y = x + y
is the curried version of this same function. This can be partially evaluated by just giving it x. For example, add 3 will evaluate to a function which will add three to its argument.
This is more clearly seen by looking at the previous examples as anonymous or lambda functions.
The first is equivalent to fn (x,y) => x + y, which clearly takes two ints and evaluates to an int.
The second is equivalent to fn x => fn y => x + y, which takes an int and evaluates to a function taking another int and evaluating to an int.
Thus, the type of the first is (int * int) -> int, while the type of the second is int -> int -> int.
Hopefully, this clears currying up somewhat.

lambda calculus for functional programming

in lambda calculus (λ x. λ y. λ s. λ z. x s (y s z)) is used for addition of two Church numerals how can we explain this, is there any good resource the lambda calculus for functional programming ? your help is much appreciated
Actually λ f1. λ f2. λ s. λ z. (f1 s (f2 s z)) computes addition because it is in effect substituting (f2 s z), the number represented by f2, to the "zero" inside (f1 s z).
Example: Let's take two for f2, s s z in expanded form. f1 is one: s z. Replace that last z by f2 and you get s s s z, the expanded form for three.
This would be easier with a blackboard and hand-waving, sorry.
In lambda calculus, you code a datatype in terms of the operations it induces. For instance, a boolean is a just a choice function that takes in input two values a and b and either returns a or b:
true = \a,b.a false = \a,b.b
What is the use of a natural number? Its main computational purpose is to
provide a bound to iteration. So, we code a natural number as an operator
that takes in input a function f, a value x, and iterate the application
of f over x for n times:
n = \f,x.f(f(....(f x)...))
with n occurrences of f.
Now, if you want to iterate n + m times the function f starting from x
you must start iterating n times, that is (n f x), and then iterate for m
additional times, starting from the previous result, that is
m f (n f x)
Similarly, if you want to iterate n*m times you need to iterate m times
the operation of iterating n times f (like in two nested loops), that is
m (n f) x
The previous encoding of datatypes is more formally explained in terms
of constructors and corresponding eliminators (the so called
Bohm-Berarducci encoding).

Resources