Generate code from specification - programming-languages

I was wondering what it is the best way to generate code, in a certain programming language P, by using a kind of specification S. Just an example:
S:
v = []
for_each x in v:
print($index, x)
P:
v = []
for i, x in enumerate(v):
print(i, x)
This is just an example for you in order to understand better my problem. I'm trying to search the best way to do that. Are there some specific algorithms that I can use?

Related

Replacing substring in second occurrence in prolog

First of all, this is not a homework. I'm studying Computer Sciences in my home, to learn a little more alone.
I'm doing an excercise. It says like this:
Construct a predicate called replaceAtomsString/4 so that given
a string s as the first parameter, a number N as the second parameter,
and a pair of atoms [g, h] (list) as the third parameter, unify in a
fourth parameter the replacement in the Nth apparition of g in s
replacing it by h. Example:
replaceAtomsString (sAbbbsAbbasA, 2, [sA, cc], X) should result in
X = sAbbbccbbasA
So, my first approach was trying to build a list with the string, just like prolog do with every string. After all, i've built this code:
substitute(X, S, T, Y) :-
append(S, Xt, X), % i.e. S is the first part of X, the rest is Xt
!,
substitute(Xt, S, T, Yt),
append(T, Yt, Y).
substitute([Xh|Xt], S, T, [Xh|Yt]) :-
substitute(Xt, S, T, Yt).
But it returns false on every attempt.
Any ideas?
Since you need substantial work to get your code done, here is how to perform the task using the available libraries.
sub_atom/5 it's a rather powerful predicate to handle atoms. Coupled with call_nth/2, the solution is straightforward and more general than what would result coding the loop around N.
replaceAtomsString(S,N,[G,H],X) :-
call_nth(sub_atom(S,Before,_,After,G),N),
sub_atom(S,0,Before,_,Left),
sub_atom(S,_,After,0,Right),
atomic_list_concat([Left,H,Right],X).
Example running your query, but leaving N to be computed:
?- replaceAtomsString(sAbbbsAbbasA, N, [sA, cc], X).
N = 1,
X = ccbbbsAbbasA ;
N = 2,
X = sAbbbccbbasA ;
N = 3,
X = sAbbbsAbbacc ;
false.

List comprehension in haskell with let and show, what is it for?

I'm studying project euler solutions and this is the solution of problem 4, which asks to
Find the largest palindrome made from the product of two 3-digit
numbers
problem_4 =
maximum [x | y<-[100..999], z<-[y..999], let x=y*z, let s=show x, s==reverse s]
I understand that this code creates a list such that x is a product of all possible z and y.
However I'm having a problem understanding what does s do here. Looks like everything after | is going to be executed everytime a new element from this list is needed, right?
I don't think I understand what's happening here. Shouldn't everything to the right of | be constraints?
A list comprehension is a rather thin wrapper around a do expression:
problem_4 = maximum $ do
y <- [100..999]
z <- [y..999]
let x = y*z
let s = show x
guard $ s == reverse s
return x
Most pieces translate directly; pieces that aren't iterators (<-) or let expressions are treated as arguments to the guard function found in Control.Monad. The effect of guard is to short-circuit the evaluation; for the list monad, this means not executing return x for the particular value of x that led to the false argument.
I don't think I understand what's happening here. Shouldn't everything to the right of | be constraints?
No, at the right part you see an expression that is a comma-separated (,) list of "parts", and every part is one of the following tree:
an "generator" of the form somevar <- somelist;
a let statement which is an expression that can be used to for instance introduce a variable that stores a subresult; and
expressions of the type boolean that act like a filter.
So it is not some sort of "constraint programming" where one simply can list some constraints and hope that Haskell figures it out (in fact personally that is the difference between a "programming language" and a "specification language": in a programming language you have "control" how the data flows, in a specification language, that is handled by a system that reads your specifications)
Basically an iterator can be compared to a "foreach" loop in many imperative programming languages. A "let" statement can be seen as introducing a temprary variable (but note that in Haskell you do not assign variable, you declare them, so you can not reassign values). The filter can be seen as an if statement.
So the list comprehension would be equivalent to something in Python like:
for y in range(100, 1000):
for z in range(y, 1000):
x = y * z
s = str(x)
if x == x[::-1]:
yield x
We thus first iterate over two ranges in a nested way, then we declare x to be the multiplication of y and z, with let s = show x, we basically convert a number (for example 15129) to its string counterpart (for example "15129"). Finally we use s == reverse s to reverse the string and check if it is equal to the original string.
Note that there are more efficient ways to test Palindromes, especially for multiplications of two numbers.

Translate list comprehension to Prolog

I have a list comprehension in Haskell that I want to translate to Prolog.
The point of the list comprehension is rotating a 4 by 4 grid:
rotate :: [Int] -> [Int]
rotate grid = [ grid !! (a + 4 * b) | a <- [0..3], b <- [0..3] ]
Now in Prolog, I translated it like this:
rotateGrid([T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15],
[T0,T4,T8,T12,T1,T5,T9,T13,T2,T6,T10,T14,T3,T7,T11,T15]).
Can we do better?
We can use findall/3 for list comprehensions (Cf. the SWI-Prolog Documentation). E.g.,
?- findall(X, between(1,10,X), Xs).
Xs = [1,2,3,4,5,6,7,8,9,10]
Xs is a list holding all values that can unify with X when X is a number between 1 and 10. This is roughly equivalent to the Haskell expression let Xs = [x | x <- [1..10]](1). You can read a findall/3 statement thus: "find all values of [First Argument] such that [Conditions in Second Argument] hold, and put those values in the list, [Third Argument]".
I've used findall/3 to write a predicate rotate_grid(+Grid, ?RotatedGrid). Here is a list of the approximate Haskell-Prolog equivalences I used in the predicate; each line shows the relation between the value that the Haskell expression will evaluate to and the Prolog variable with the same value:
a <- [0..3] = A in between(0, 3, A)
b <- [0..3] = B in between(0, 3, B)
(a + 4 * d) = X in X is A + 4 * D
<Grid> !! <Index> = Element in nth0(Index, Grid, Element)
Then we simply need to find all the values of Element:
rotate_grid(Grid, RotatedGrid) :-
findall( Element,
( between(0,3,A),
between(0,3,B),
Index is A + 4 * B,
nth0(Index, Grid, Element) ),
RotatedGrid
).
To verify that this produces the right transformation, I down-cased the Prolog code from the question and posed the following query:
?- rotate_grid([t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15],
[t0,t4,t8,t12,t1,t5,t9,t13,t2,t6,t10,t14,t3,t7,t11,t15]).
| true.
Footnotes:
(1): between/3 isn't actually the analogue of [m..n], since the latter returns a list of values from m to n where between(M,N,X) will instantiate X with each value between M and N (inclusive) on backtracking. To get a list of numbers in SWI-Prolog, we can use numlist(M,N,Ns). So a stricter analogue for x <- [1.10] would be the conjunction member(X, Ns), numlist(1, 10, Ns).
You want a permutation of a list. The concrete elements are not considered. Therefore, you can generalize your Haskell signature to
rotate :: [x] -> [x]
This is already a very valuable hint for Prolog: the list's elements will not be considered - elements will not even be compared. So a Prolog solution should be able to handle variables directly, like so:
?- rotateGrid(L,R).
L = [_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P],
R = [_A,_E,_I,_M,_B,_F,_J,_N,_C,_G,_K,_O,_D,_H,_L,_P].
And your original definition handles this perfectly.
Your version using list comprehensions suggests itself to be realized via backtracking, certain precautions have to be taken. Using findall/3, as suggested by #aBathologist will rename variables:
?- length(L,16),rotate_grid(L,R).
L = [_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P],
R = [_Q,_R,_S,_T,_U,_V,_W,_X,_Y,_Z,_A1,_B1,_C1,_D1,_E1,_F1].
The built-in predicate bagof/3 addresses this problem. Note that we have to declare all local, existential variables explicitly:
rotate_grid2(Grid, RotatedGrid) :-
bagof(
Element,
A^B^Index^ % declaration of existential variables
( between(0,3,A),
between(0,3,B),
Index is A + 4 * B,
nth0(Index, Grid, Element)
),
RotatedGrid).
For lists that are shorter than 16 elements, the Haskell version produces a clean error, but here we get pretty random results:
?- L=[1,2,3,4],rotate_grid(L,R).
L = [1,2,3,4], R = [1,2,3,4].
?- L=[1,2,3,4,5],rotate_grid(L,R).
L = [1,2,3,4,5], R = [1,5,2,3,4].
This is due to the unclear separation between the part that enumerates and "generates" a concrete element. The cleanest way is to add length(Grid, 16) prior to the goal bagof/3.
List comprehensions in Prolog
Currently, only B-Prolog offers a form of list comprehensions:
R#=[E: A in 0..3,B in 0..3,[E,I],(I is A+4*B,nth0(I,L,E))].
However, it does not address the second problem:
| ?- L = [1,2,3], R#=[E: A in 0..3,B in 0..3,[E,I],(I is A+4*B,nth0(I,L,E))].
L = [1,2,3]
R = [1,2,3]
yes
Use a loop predicate foreach/4
If the comprehension should retain variables, which is for example important in constraint programming, a Prolog system could offer a predicate foreach/4. This predicate is the DCG buddy of foreach/2.
Here is how variables are not retained via findall/3, the
result R contains fresh variables according to the ISO
core semantics of findall/3:
Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.1)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
?- functor(L,foo,5), findall(X,
(between(1,5,N), M is 6-N, arg(M,L,X)), R).
L = foo(_5140, _5142, _5144, _5146, _5148),
R = [_5210, _5204, _5198, _5192, _5186].
And here is how variables can be retained via foreach/4,
the resulting list has the same variables as the compound
we started with:
Jekejeke Prolog 3, Runtime Library 1.3.0
(c) 1985-2018, XLOG Technologies GmbH, Switzerland
?- [user].
helper(N,L) --> [X], {M is 6-N, arg(M,L,X)}.
Yes
?- functor(L,foo,5), foreach(between(1,5,N),helper(N,L),R,[]).
L = foo(_A,_G,_M,_S,_Y),
R = [_Y,_S,_M,_G,_A]
Using foreach/4 instead of bagof/3 might seem a little bit over the top. foreach/4 will probably only show its full potential when implementing Picat loops, since it can build up constraints, what bagof/3 cannot do.
foreach/4 is an implementation without the full materialization of all solution that are then backtracked. It shares with bagof/3 the reconstruct of variables, but still allows backtracking in the conjunction of the closures.

OCaml : need help for List.map function

I need to create a function that basically works like this :
insert_char("string" 'x') outputs "sxtxrxixnxg".
So here is my reasoning :
Create a list with every single character in the string :
let inserer_car(s, c) =
let l = ref [] in
for i = 0 to string.length(s) - 1 do
l := s.[i] :: !l
done;
Then, I want to use List.map to turn it into a list like ['s', 'x', 't', 'x' etc.].
However, I don't really know how to create my function to use with map. Any help would be appreciated!
I'm a beginner in programming and especially in ocaml! so feel free to assume I'm absolutely ignorant.
If you were using Core, you could write it like this:
open Core.Std
let insert_char s c =
String.to_list s
|> (fun l -> List.intersperse l c)
|> String.of_char_list
Or, equivalently:
let insert_char s c =
let chars = String.to_list s in
let interspersed_chars = List.intersperse chars c in
String.of_char_list interspersed_chars
This is just straightforward use of existing librariies. If you want the implementation of List.intersperse, you can find it here. It's quite simple.
A map function creates a copy of a structure with different contents. For lists, this means that List.map f list has the same length as list. So, this won't work for you. Your problem requires the full power of a fold.
(You could also solve the problem imperatively, but in my opinion the reason to study OCaml is to learn about functional programming.)
Let's say you're going to use List.fold_left. Then the call looks like this:
let result = List.fold_left myfun [] !l
Your function myfun has the type char list -> char -> char list. In essence, its first parameter is the result you've built so far and its second parameter is the next character of the input list !l. The result should be what you get when you add the new character to the list you have so far.
At the end you'll need to convert a list of characters back to a string.

Prolog find all paths Implementation

I've been tasked to implement a version of findall in Prolog without using any Prolog built-ins except for not and cut - so basically in pure Prolog.
I'm trying to search a tree for all direct descendants and return the results in a list
parent(a, b).
parent(b, c).
parent(b, d).
parent(e, d).
What I have so far is:
find(X, L) :- find2(X, [], L).
find2(X, Acc, L) :- parent(Y, X), find2(Y, [Y|Acc], L).
find2(_, Acc, Acc).
What I want to be getting when I enter for example:
find(a,X).
would be:
X = [b, c, d]
(Order not important)
However instead I am getting:
X = [b, c] ;
X = [b, d] ;
X = [b] ;
X = [].
I'm new to Prolog so any help on this would be much appreciated.
Thanks
Besides asserting data as you go, you can also use an extra-logical predicate such as nb_setarg/3. Then once a parent is found, you fail back past nb_setarg and find another parent. All previously found solutions should stay in the term you did nb_setarg on, then after all results are exhausted, the nb_setarg term is the answer. The SWI-Prolog example is good, but its just a counter. Try doing it with a list (or better yet: difference list) that builds as you go.
Take a look at this solution.
Note that this solution uses dynamic predicate named queue in order to cache all solutions until all possibilities are exhausted. Once no more solution exists, implementation retracts all facts and composes the list.
This is of course a bit simplified solution, imagine what would happen if two findall would be active at the same time. It is also a bit fragile on exact semantics of assert and retract if particular prolog implementation
Thanks for you help everyone. I managed to solve it in the end by adding a predicate which checked each item against the current list, and failed if it was already present:
find(X, Loa) :- find(X, [], Loa), !.
find(X, Acc, Loa) :- dec(X, Y), uList(Y, Acc, AccNew), find(X, AccNew, Loa).
find(_, Acc, Acc).
dec(X,Y) :- parent(X,Y).
dec(X,Y) :- parent(X,Z), dec(Z,Y).
uList(X, [], [X]) :- !.
uList(H, [H|_], _) :- !, fail.
uList(X, [H|T], L) :- uList(X, T, Rtn), L = [H|Rtn].

Resources