The examples used here are from the weekly challenge problem statement and demonstrate the working solution. Also, the challenge statements are given in a Perl context although for Prolog solutions some adjustments are made to account for the differing semantics between the two languages.
You are given a text file. Write a script to display all valid phone numbers in the given text file.
:-initialization(main). test('0044 1148820341'). test('+44 1148820341'). test('44-11-4882-0341'). test('(44) 1148820341'). test('00 1148820341'). phone_number --> prefx, space, area_exchange_subscriber. prefx --> ['('], digit, digit, [')']. prefx --> ['+'], digit, digit. prefx --> digit, digit, digit, digit. space --> [' ']. area_exchange_subscriber --> digit, digit, digit, digit, digit, digit, digit, digit, digit, digit. digit --> ['0']; ['1']; ['2']; ['3']; ['4']; ['5']; ['6']; ['7']; ['8']; ['9']. run_tests:- test(T), atom_chars(T, C), phrase(phone_number, C), write(T), nl. main:- run_tests.
$$ gprolog --consult-file prolog/ch-1.p GNU Prolog 1.4.5 (32 bits) Compiled Dec 3 2020, 00:37:14 with gcc By Daniel Diaz Copyright (C) 1999-2020 Daniel Diaz compiling /home/adamcrussell/Projects/perlweeklychallenge-club/challenge-110/adam-russell/prolog/ch-1.p for byte code... /home/adamcrussell/Projects/perlweeklychallenge-club/challenge-110/adam-russell/prolog/ch-1.p compiled, 27 lines read - 5899 bytes written, 78 ms | ?- run_tests. 0044 1148820341 true ? ; +44 1148820341 true ? ; (44) 1148820341 true ? ; (1 ms) no
I skipped anything to do with actually reading the numbers from a file since that doesn’t really add to the interesting part of the problem. Instead the possible phone numbers to test are just stored in the Prolog db.
Testing is done via DCG. The DCG is a bit rotely written, for sure! DCG’s are a bit hard to debug so I thought I’d start out writing things out as obviously as possible and then come back to tighten things up. Coming back to the DCG later on, I thought there was something kind of attractive to the thing, as it is a bit close to the grammar I wrote in the Perl version of the solution. Perhaps someone looking at the Perl grammar would look at this and even not knowing Prolog be able to make perfect sense of it.
You are given a text file. Write a script to transpose the contents of the given file.
:-initialization(main). transpose(Columns, Transposed):- transpose(Columns, _, Transposed). transpose(, Transposed, Transposed). transpose([H|T], TransposedAccum, Transposed):- transpose_row(H, TransposedAccum, TransposedAccumNew), reverse(TransposedAccumNew, TransposedAccumNewReversed), transpose(T, TransposedAccumNewReversed, Transposed). transpose_row(Row, TransposedAccum, RowTranspose):- transpose_row(Row, TransposedAccum, , RowTranspose). transpose_row(, , RowTranspose, RowTranspose). transpose_row([H|T], [HAccum|TAccum], RowTransposeAccum, RowTranspose):- append(HAccum, H, HAccum0), flatten(HAccum0, HAccum1), transpose_row(T, TAccum, [HAccum1 | RowTransposeAccum], RowTranspose). main:- transpose([[1,2,3],[4,5,6]], Transposed), write(Transposed), nl.
$ gprolog --consult-file prolog/ch-2.p GNU Prolog 1.4.5 (32 bits) Compiled Dec 3 2020, 00:37:14 with gcc By Daniel Diaz Copyright (C) 1999-2020 Daniel Diaz compiling /home/adamcrussell/Projects/perlweeklychallenge-club/challenge-110/adam-russell/prolog/ch-2.p for byte code... /home/adamcrussell/Projects/perlweeklychallenge-club/challenge-110/adam-russell/prolog/ch-2.p compiled, 23 lines read - 2766 bytes written, 43 ms [[1,4],[2,5],[3,6]]
Again, I skip over reading test data from a file and focus just on transposing a hardcoded table. This is fairly straightforward, and is another list processing exercise that would be well served by using DCGs, but the non-DCG approach seems to otherwise be a fairly standard exercise in recursion.