Matching values in a tuple through a map - tuples

I'm trying to make a function like this essentially
eval(X, Map = #{}) ->
%% expression
.
X is supposed to be a tuple that will contain three elements, with the first one being a description. The other values can be either integers, or they can be the atom a or b, or another tuple. The second parameter is supposed to be a map that will map any potential atom a or b in X to a value. Example inputs can be
eval({add, a, b}, #{a => 1, b => 2})
eval({add, a, 2}, #{a => 1})
eval({mul, {add, a, 3}, b}, #{a => 1, b => 2}).
I for the life of me cannot find a way to have Map, map any potential atom a or b in X to the values given in the input. Anyone has a suggestion for how to implement so that any atom a or b are mapped to vales given in Map?

As suggested by other folks at Map pattern matching in function head (Although this question has a far clearer description), what you are looking for is something along the lines of…
eval({Op, a, b}, #{a := A, b := B}) ->
eval(Op, A, B);
eval({Op, A, b}, #{b := B}) ->
eval(Op, A, B);
eval({Op, a, B}, #{a := A}) ->
eval(Op, A, B);
eval({Op, A, B}, _) ->
eval(Op, A, B).
eval(add, A, B) ->
A + B;
eval(mul, A, B) ->
A * B;
…

Modifications to the already posted answer by #BrujoBenavides to handle nested tuples:
eval({Op, a, b}, #{a := A, b := B}) ->
eval(Op, A, B);
eval({Op, a, B}, #{a := _} = Map) when is_integer(B) ->
eval({Op, a, b}, Map#{b => B});
eval({Op, a, Expr}, #{a := _} = Map) ->
B = eval(Expr, Map),
eval({Op, a, b}, Map#{b => B});
eval({Op, A, b}, #{b := _} = Map) when is_integer(A) ->
eval({Op, a, b}, Map#{a => A});
eval({Op, Expr, b}, #{b := _} = Map) ->
A = eval(Expr, Map),
eval({Op, a, b}, Map#{a => A});
eval({Op, A, B}, _) when is_integer(A), is_integer(B) ->
eval({Op, a, b}, #{a => A, b => B});
eval({Op, Expr1, Expr2}, #{} = Map) ->
%% need to evaluate Expr1 and Expr2 before Op
A = eval(Expr1, Map),
B = eval(Expr2, Map#{a => A}),
eval({Op, a, b}, Map#{a => A, b => B}).
eval(add, A, B) ->
A+B;
eval(sub, A, B) ->
A - B;
eval(mul, A, B) ->
A * B;
eval('div', A, B) ->
A div B.

Related

Combing odd and even regular expression to regular grammar?

I have this class that I need to write regular grammar for. The grammar is {a,b,c} where there are an odd number of a's and c's, but an even number of b's.
Examples of good strings:
babc
abcb
cbba
accaccac
ac
Bad strings
babcb
abc
cbbca
accacca
aa
*empty string
My regex for even b's is b∗(ab∗ab∗)∗b∗ (I don't know where to include c)
My regex for odd a's is (c|a(b|c)*a)*a(b|c)*
My regex for odd c's is (c|a(b|c)*c)*c(b|c)*
I'm thinking that a regular grammar would look something like this:
s -> [a], a
s -> [c], c
a -> [a], a
a -> [b], b
a -> [c], c
b -> [b]
b -> [b], b
b -> [a], a
b -> [c], c
c -> [c], c
c -> [a], a
c -> [b], b
I think it's evident that I'm very lost. Any help is appreciated!
Here is a possible solution in SWI-Prolog:
:- use_module(library(clpfd)).
:- use_module(library(lambda)).
odd_even(Lst) :-
variables_signature(Lst, Sigs),
automaton(Sigs, _, Sigs,
% start in s, end in i
[source(s), sink(i)],
% if we meet 0, counter A of a is incremented of one modulo 2
% the others are unchanged
[arc(s, 0, s, [(A+1) mod 2, B, C]),
arc(s, 1, s, [A, (B+1)mod 2, C]),
arc(s, 2, s, [A, B, (C+1) mod 2]),
arc(s, 0, i, [(A+1) mod 2, B, C]),
arc(s, 1, i, [A, (B+1)mod 2, C]),
arc(s, 2, i, [A, B, (C+1) mod 2])],
% name of counters
[A, B, C],
% initial values of counters
[0, 0, 0],
% needed final values of counters
[1,0,1]).
% replace a with 0, b with 1, c with 2
variables_signature(Lst, Sigs) :-
maplist(\X^Y^(X = a -> Y = 0; (X = b -> Y = 1; Y = 2)), Lst, Sigs).
Example :
?- odd_even([a,c,c,a,c,c,a,c]).
true.
?- odd_even([a,c,c,a,c,c,a]).
false.

Prolog - Generate alternating symbols on backtrack: [a] ; [a,b]; [a,b,a]; [a,b,a,b]

I've wrapped my mind a lot and couldn't figure it out.
Is it possible to make a script that with backtrack generates lists in this format:
[a]
[a,b]
[a,b,a]
[a,b,a,b]
...
I've made one that generates two elements at a time but my head started to hurt trying to make one that generates "a" and the next time "b" and the next "a" and so on.
Here is the script for two elements at a time:
ab([a]).
ab([b,a|T]):-ab([a|T]).
ab([a,b|T]):-ab([b|T]).
When describing lists, always consider using DCG notation.
This makes it very convenient to focus an the essence of what you want to describe, without so many additional variables and arguments.
For example, consider:
abs --> [a], abs_rest.
abs_rest --> [].
abs_rest --> [b], ( [] | abs ).
Sample query and answer:
?- phrase(abs, ABs).
ABs = [a] ;
ABs = [a, b] ;
ABs = [a, b, a] ;
ABs = [a, b, a, b] ;
ABs = [a, b, a, b, a] ;
ABs = [a, b, a, b, a, b] .
See dcg for more information about this convenient formalism!
I agree with #mat that one should use dcg when possible for these type of problems.
Here is a different set of rules.
abs --> [a].
abs --> [a,b].
abs --> [a,b], abs.
?- phrase(abs, Ls).
Ls = [a] ;
Ls = [a, b] ;
Ls = [a, b, a] ;
Ls = [a, b, a, b] ;
Ls = [a, b, a, b, a] ;
Ls = [a, b, a, b, a, b] ;
Ls = [a, b, a, b, a, b, a] ;
Ls = [a, b, a, b, a, b, a, b] ;
Ls = [a, b, a, b, a, b, a, b, a]
Interestingly those rules started from this variation
abs2 --> [].
abs2 --> [a].
abs2 --> [a,b], abs2.
?- phrase(abs2, Ls).
Ls = [] ;
Ls = [a] ;
Ls = [a, b] ;
Ls = [a, b, a] ;
Ls = [a, b, a, b] ;
Ls = [a, b, a, b, a] ;
Ls = [a, b, a, b, a, b] ;
Ls = [a, b, a, b, a, b, a] ;
Ls = [a, b, a, b, a, b, a, b]
which is one of the exercises from Using Definite Clause Grammars in SWI-Prolog
If you prefer not to use DCG, then I agree with #mat and suggest that you use listing/1 to see the DCG in standard Prolog syntax.
listing(abs).
abs([a|A], A).
abs([a, b|A], A).
abs([a, b|A], B) :-
abs(A, B).
listing(abs2).
abs2(A, A).
abs2([a|A], A).
abs2([a, b|A], B) :-
abs2(A, B).
As normal Prolog rules they can be used as such:
abs(X,[]).
X = [a] ;
X = [a, b] ;
X = [a, b, a] ;
X = [a, b, a, b] ;
X = [a, b, a, b, a] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b, a]
abs2(X,[]).
X = [] ;
X = [a] ;
X = [a, b] ;
X = [a, b, a] ;
X = [a, b, a, b] ;
X = [a, b, a, b, a] ;
X = [a, b, a, b, a, b]
The predicate you wrote is too general:
?- ab([b,a]).
true
The cause is the following rule
ab([b,a|T]) :-
ab([a|T]).
One could say that you describe an intermediate result which is no solution to your actual problem. To fix this, you could state than an ab sequence starts with a and the rest bust be a ba sequence, where ba sequences are again defined in terms of ab sequences:
ab([a]).
ab([a|Xs]) :-
ba(Xs).
ba([b]).
ba([b|Xs]) :-
ab(Xs).
Alternatively, you could think of abs as a state machine which
produces a whenever the last element was b and vice versa.
If we introduce an additional argument to trace the history, we arrive at:
abs(a,[a]).
abs(b,[b]).
abs(a,[a|Xs]) :-
abs(b,Xs).
abs(b,[b|Xs]) :-
abs(a,Xs).
Now we define an ab sequence as one which last prepended an a:
ab(Xs) :-
abs(a,Xs).
Have fun :)

Proving the Continuation Passing Style Monad in Coq

I'm trying to prove the Monad laws (left and right unit + associativity) for the Continuation Passing Style (CPS) Monad.
I'm using a Type Class based Monad defintion from https://coq.inria.fr/cocorico/AUGER_Monad:
Class Monad (m: Type -> Type): Type :=
{
return_ {A}: A -> m A;
bind {A B}: m A -> (A -> m B) -> m B;
right_unit {A}: forall (a: m A), bind a return_ = a;
left_unit {A}: forall (a: A) B (f: A -> m B),
bind (return_ a) f = f a;
associativity {A B C}:
forall a (f: A -> m B) (g: B -> m C),
bind a (fun x => bind (f x) g) = bind (bind a f) g
}.
Notation "a >>= f" := (bind a f) (at level 50, left associativity).
The CPS type constructor is from Ralf Hinze's Functional Pearl about Compile-time parsing in Haskell
Definition CPS (S:Type) := forall A, (S->A) -> A.
I defined bind and return_ like this
Instance CPSMonad : Monad CPS :=
{|
return_ := fun {A} a {B} => fun (f:A->B) => f a ;
bind A B := fun (m:CPS A) (k: A -> CPS B)
=>(fun C => (m _ (fun a => k a _))) : CPS B
|}.
but I'm stuck with the proof obligations for right_unit and associativity.
- unfold CPS; intros.
gives the obligation for right_unit:
A : Type
a : forall A0 : Type, (A -> A0) -> A0
============================
(fun C : Type => a ((A -> C) -> C) (fun (a0 : A) (f : A -> C) => f a0)) = a
Would be very grateful for help!
EDIT: András Kovács pointed out that eta conversion in the type checker is sufficient, so intros; apply eq_refl., or reflexivity. is enough.
Bur first I had to correct my incorrect definition of bind. (The invisible argument c was on the wrong side of the )...
Instance CPSMonad : Monad CPS :=
{|
return_ S s A f := f s ;
bind A B m k C c := m _ (fun a => k a _ c)
|}.
The solution, as mentioned in a comment by András Kovács on Mar 11 at 12:26, is
Maybe you could try going straight for reflexivity? From Coq 8.5 there's eta conversion for records, so all the laws should be apparent immediately by normalization and eta conversion.
That gives us the following instance:
Instance CPSMonad : Monad CPS :=
{|
return_ S s A f := f s ;
bind A B m k C c := m _ (fun a => k a _ c) ;
right_unit A a := eq_refl ;
left_unit A a B f := eq_refl ;
associativity A B C a f g := eq_refl
|}.

Find all possible pairs

Im working on some erlang code and want to create a recursive function for extracting all possible pairs from a list. The list could have zero elements, but it could have up to 70 elements. Writing cases for all of these occurrences is bad practice and I would like your help.
pair(List) ->
case List of
[] -> [];
[A] -> [{A}];
[A, B] -> [{A, B}, {B, A}];
[A, B, C] -> [{A, B}, {A, C}, {B, A}, {B, C}, {C, A}, {C, B}];
end.
I found a function written to create a list of all possible combinations (not only all pairs), but I don't understand how to change it.
combos(1, L) -> [[X] || X <-L];
combos(K, L) when K == length(L) -> [L];
combos(K, [H|T]) ->
[[H | Subcombos] || Subcombos <- combos(K-1, T)]
++(combos(K, T)).
combos(L) ->
lists:foldl(
fun(K, Acc) -> Acc++(combos(K, L)) end,
[[]], lists:seq(1, length(L))).
You can use a list comprehension and reference the same list twice as an input:
1> L = [a,b,c,d].
[a,b,c,d]
2> [{X, Y} || X <- L, Y <- L].
[{a,a},
{a,b},
{a,c},
{a,d},
{b,a},
{b,b},
{b,c},
{b,d},
{c,a},
{c,b},
{c,c},
{c,d},
{d,a},
{d,b},
{d,c},
{d,d}]
I'd be surprised if there was any clearer or more efficient way to do this.
EDIT
In the event you don't want identical pairs ({a,a} and so on) you can add a guard to ensure inequality:
5> [{X, Y} || X <- L1, Y <- L1, X /= Y].
[{a,b},
{a,c},
{a,d},
{b,a},
{b,c},
{b,d},
{c,a},
{c,b},
{c,d},
{d,a},
{d,b},
{d,c}]

How to apply function to a list in incremental manner?

Having a list of
{a, b, c, d}
and a function
f
I wish to get a list
{f[a], f[a,b], f[a,b,c], f[a,b,c,d]}
What is the simplest way to do this?
f ### ({a, b, c, d}[[1 ;; #]] & /# Range[4])
{f[a], f[a, b], f[a, b, c], f[a, b, c, d]}
This is not exactly simple, but it works
lst = {a, b, c, d};
Block[{f}, SetAttributes[f, Flat]; FoldList[f, f#First##, Rest##]]& # lst
(* {f[a], f[a, b], f[a, b, c], f[a, b, c, d]} *)
This, too, based on my answer to a very similar question:
f ### FoldList[#1~Join~{#2} &, {First##}, Rest##]& # lst
(* {f[a], f[a, b], f[a, b, c], f[a, b, c, d]} *)
Some other formulations:
f ## Take[{a, b, c, d}, #] & ~Array~ 4
f[a, b, c, d] ~Take~ # & ~Array~ 4
Rest # FoldList[Append, f[], {a, b, c, d}]
All but the first may evaluate f in an undesired way but you could use Block to prevent that.
f = Print;
Block[{f},
f[a, b, c, d] ~Take~ # & ~Array~ 4
]
a
ab
abc
abcd