% % Copilot test in Picat. % % This is to be run in Visual Studio Code. % % Most of this has been created by Copilot % with a little help/editing from Hakan Kjellerstrand (hakank@gmail.com). % Some of it is not correct or plain nonsense. % % Copilot think this is Prolog and that's not very wrong. % One drawback is that Copilot just generate one clause at each time, % so multiples clauses might have to be generated to get the correct result. % This comment was generated by Copilot: % But this is not a problem for the test. And it is not a problem, because % the test is not very long. And the test is not very long, because the % test is not very long. % import cp. main => go. % These go*/0 was written by hakank go ?=> member(X, [1,2,3,4,5,6,7,8,9]), rotate([1,2,3], X, R), println(X=R), fail, nl. go => true. % hakank: Not correct go2 ?=> member(X,1..20), isprime(X), println(X), fail, nl. go2 => true. % Not correct go3 ?=> search('x', "xboxing", X), println(X), nl. go3 => true. % hakank: This is just silly and it continues like than on and on.... isprime(2). isprime(3). isprime(X) :- X > 3, not(divisible(X, 3)). isprime(X) :- X > 5, not(divisible(X, 5)). isprime(X) :- X > 7, not(divisible(X, 7)). isprime(X) :- X > 11, not(divisible(X, 11)). isprime(X) :- X > 13, not(divisible(X, 13)). isprime(X) :- X > 17, not(divisible(X, 17)). isprime(X) :- X > 19, not(divisible(X, 19)). divisible(X, Y) :- 0 is X mod Y. rotate(L, N, R) :- length(L, Len), N1 is N mod Len, rotate_aux(L, N1, R). rotate_aux([], _, []). rotate_aux(L, 0, L). rotate_aux([H|T], N, [H|R]) :- N1 is N - 1, rotate_aux(T, N1, R). length([], 0). length([_|T], N) :- length(T, N1), N is N1 + 1. % hakank: I renamed it from member/2 since it clashes with the built-in memberx(X, [X|_]). memberx(X, [_|T]) :- memberx(X, T). % hakank: This works sort([], []). sort([X|Xs], S) :- partition(Xs, X, Ys, Zs), sort(Ys, Ys1), sort(Zs, Zs1), append(Ys1, [X|Zs1], S). partition([], _, [], []). partition([X|Xs], Y, [X|Ys], Zs) :- X =< Y, partition(Xs, Y, Ys, Zs). partition([X|Xs], Y, Ys, [X|Zs]) :- X > Y, partition(Xs, Y, Ys, Zs). % Search for a string in a list: % hakank: Don't work search([], _, _). search([H|T], S, R) :- search_aux(H, S, R), !. search([_|T], S, R) :- search(T, S, R). search_aux(H, S, R) :- appendx(S, [], H), !, R = H. search_aux(_, _, _). appendx([], L, L). appendx([H|T], L, [H|R]) :- appendx(T, L, R). % hakank: Almost automatically generated hint text: % Calculate the number of ways to make change for a given amount of money % and a given list of coin denominations. % hakank: % Picat> change(10,[1,2],X) % X = 9 ?; % X = 10 ?; % X = 9 ?; % X = 10 % change(0, _, 0). change(Amount, [], Amount). change(Amount, [Coin|Coins], Count) :- Amount >= Coin, NewAmount is Amount - Coin, change(NewAmount, Coins, Count1), Count is Count1 + 1. change(Amount, [_|Coins], Count) :- change(Amount, Coins, Count). % hakank: Not correct! gcd(X, 0, X). gcd(X, Y, R) :- X < Y, gcd(Y, X, R). gcd(X, Y, R) :- X > Y, gcd(X, Y, R). lcmm(X, 0, X). lcmm(X, Y, R) :- X < Y, lcmm(Y, X, R). lcmm(X, Y, R) :- X > Y, lcmm(X, Y, R). % not correct findall(X, P, R) :- findall_aux(X, P, [], R). findall_aux(X, P, L, R) :- call(P, X), !, appendx(L, [X], L1), findall_aux(X, P, L1, R). findall_aux(_, _, R, R). % Define a predicate to generate all the permutations of a list permutation([], []). permutation([H|T], R) :- permutation(T, T1), insert(H, T1, R). insert(X, [], [X]). insert(X, [H|T], [X,H|T]). insert(X, [H|T], [H|R]) :- insert(X, T, R). % Define a predicate to generate all the combinations of a list % hakank: But this is actually permutation/2 combination([], []). combination([H|T], R) :- combination(T, T1), insert(H, T1, R). % hakank: This works fib(0, 0). fib(1, 1). fib(N, R) :- N > 1, N1 is N - 1, N2 is N - 2, fib(N1, R1), fib(N2, R2), R is R1 + R2. % Generate tribonacci numbers tribonacci(0, 0). tribonacci(1, 1). tribonacci(2, 1). tribonacci(N, R) :- N > 2, N1 is N - 1, N2 is N - 2, N3 is N - 3, tribonacci(N1, R1), tribonacci(N2, R2), tribonacci(N3, R3), R is R1 + R2 + R3. % hakank: Don't work perfect(N) :- N > 1, N1 is N - 1, sum_divisors(N, S), println(s=S), S = N1. sum_divisors(N, S) :- sum_divisors_aux(N, N, S). sum_divisors_aux(N, I, S) :- I = 1, S is N. sum_divisors_aux(N, I, S) :- I > 1, I1 is I - 1, (N mod I = 0, S1 is S + I ; S1 is S ), sum_divisors_aux(N, I1, S1). password_generator(N, R) :- password_generator_aux(N, [], R). password_generator_aux(N, L, R) :- N = 0, !, R = L. password_generator_aux(N, L, R) :- N > 0, N1 is N - 1, password_generator_aux(N1, L, R1), % random(1,10,R2) R2 = random(1, 10), % hakank: Changed to Picat's version of random % append(L, R2, L1), % hakank: original append(L, [R2|R1], L1), % hakank: Changed to this R = L1. % If Copilot don't know what to do it use a simple pattern, like the following. % They have a nice base case, but where is the rest... % generate a poem poem(N, R) :- poem_aux(N, [], R). poem_aux(N, L, R) :- N = 0, !, R = L. password(N, R) :- password_aux(N, [], R). password_aux(N, L, R) :- N = 0, !, R = L. xyxxy(N, R) :- xyxxy_aux(N, [], R). xyxxy_aux(N, L, R) :- N = 0, !, R = L. % hakank: Well, it looks nice, doesn't it unionfind(X, Y, R) :- unionfind_aux(X, Y, [], R). unionfind_aux(X, Y, L, R) :- X = Y, !, appendx(L, [X], L1), unionfind_aux(X, Y, L1, R). unionfind_aux(X, Y, L, R) :- X \= Y, appendx(L, [X], L1), unionfind_aux(X, Y, L1, R). % hakank: This works palindrome(L) :- reverse(L, L). reverse([], []). reverse([H|T], R) :- reverse(T, R1), appendx(R1, [H], R). % Copilot used appendx/3 instead of append/3. Quite nice. % convert a binary number to a decimal number % hakank: % Picat> binary_to_decimal(11,X) % X = 2047 binary_to_decimal(0, 0). binary_to_decimal(B, D) :- B > 0, B1 is B - 1, binary_to_decimal(B1, D1), D is 2 * D1 + 1. % convert a decimal number to a binary number % hakank: Don't work decimal_to_binary(D, B) :- % println($decimal_to_binary(D, B) ), % hakank: Copilot added this line since I added a simular to binary_to_decimal D > 0, D1 is D - 1, decimal_to_binary(D1, B1), B is B1 + 1. % convert a number to a number in a base % N: number to convert % R: result % B: base % hakank: Nice, but not correct... radix(N, R, B) :- radix_aux(N, R, B, 0). radix_aux(N, R, B, I) :- N = 0, !, R = I. radix_aux(N, R, B, I) :- N > 0, N1 is N - 1, radix_aux(N1, R1, B, I1), I is I1 * B + R1. % hakank: creative but weird,,, magic_square :- magic_square_aux(3, [[1,2,3], [4,5,6], [7,8,9]]). magic_square_aux(N, S) :- N > 0, N1 is N - 1, magic_square_aux(N1, S1), magic_square_aux_aux(N, S1, S). magic_square_aux_aux(N, S1, S) :- N = 1, !, S = S1. magic_square_aux_aux(N, S1, S) :- N > 1, N1 is N - 1, magic_square_aux_aux(N1, S1, S2), magic_square_aux_aux_aux(N, S1, S2, S). magic_square_aux_aux_aux(N, S1, S2, S) :- N = 1, !, S = S1. magic_square_aux_aux_aux(N, S1, S2, S) :- N > 1, N1 is N - 1, magic_square_aux_aux_aux(N1, S1, S2, S3), magic_square_aux_aux_aux_aux(N, S1, S2, S3, S). magic_square_aux_aux_aux_aux(N, S1, S2, S3, S) :- N = 1, !, S = S1. magic_square_aux_aux_aux_aux(N, S1, S2, S3, S) :- N > 1, N1 is N - 1, magic_square_aux_aux_aux_aux(N1, S1, S2, S3, S4), magic_square_aux_aux_aux_aux_aux(N, S1, S2, S3, S4, S). magic_square_aux_aux_aux_aux_aux(N, S1, S2, S3, S4, S) :- N = 1, !, S = S1. magic_square_aux_aux_aux_aux_aux(N, S1, S2, S3, S4, S) :- N > 1, N1 is N - 1, magic_square_aux_aux_aux_aux_aux(N1, S1, S2, S3, S4, S5), magic_square_aux_aux_aux_aux_aux_aux(N, S1, S2, S3, S4, S5, S). % and so it continues.... % hakank: I added this manually to skip the warning about not defined predicate magic_square_aux_aux_aux_aux_aux_aux(N, S1, S2, S3, S4, S5, S). % hakank: It generates solutions such as % Picat> langford(10,R) % R = [[1,0],[2,1],[3,2],[4,3],[5,4],[6,5],[7,6],[8,7],[9,8],[10,9]] % Which - of course - is not a Langford solution. langford(N, R) :- langford_aux(N, [], R). langford_aux(N, L, R) :- N = 0, !, R = L. langford_aux(N, L, R) :- N > 0, N1 is N - 1, langford_aux(N1, L1, R1), appendx(L1, [N], L2), appendx(L2, [N1], L3), appendx(R1, [L3], R).