Created
January 21, 2026 21:19
-
-
Save podikoglou/28f30c5167c540fa3a991ece2bd4e898 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*---------------------------------------------------------------------------- | |
| CCS2200 Logic Programming | |
| Porfolio Submission Fall 2025 | |
| Student ID: <redacted> | |
| Date of submission: 21/1/2026 | |
| ----------------------------------------------------------------------------*/ | |
| /*---------------------------------------------------------------------------- | |
| EXERCISE NUMBER: 5 | |
| ----------------------------------------------------------------------------*/ | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: sum/2 | |
| TEXTUAL DECRIPTION: sums numbers in a list | |
| QUERIES & ANSWERS: | |
| ?- sum([4,8,12], S). | |
| S = 24 . | |
| ----------------------------------------------------------------------------*/ | |
| sum([], 0). | |
| sum([H], H). | |
| sum([H|T], O) :- | |
| sum(T, S1), | |
| O is H + S1. | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: avg/2 | |
| TEXTUAL DECRIPTION: computes the average of the numbers in a list | |
| QUERIES & ANSWERS: | |
| ?- avg([4,8,12], S). | |
| S = 8 . | |
| ----------------------------------------------------------------------------*/ | |
| avg([], 0). | |
| avg(L, O) :- | |
| sum(L, S), | |
| length(L, Len), | |
| O is S / Len. | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: filter_positive/2 | |
| TEXTUAL DECRIPTION: finds the positive numbers in a list | |
| QUERIES & ANSWERS: | |
| ?- filter_positive([-2, -4, 3, 8, -1], P). | |
| P = [3, 8]. | |
| ----------------------------------------------------------------------------*/ | |
| filter_positive(L, O) :- | |
| findall(X, (member(X, L), X > 0), O). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: filter_even/2 | |
| TEXTUAL DECRIPTION: finds the even numbers in a list | |
| QUERIES & ANSWERS: | |
| ?- filter_even([-2, 4, 3, 8, 1], P). | |
| P = [-2, 4, 8]. | |
| ----------------------------------------------------------------------------*/ | |
| filter_even(L, O) :- | |
| findall(X, ( | |
| member(X, L), | |
| M is X mod 2, | |
| M is 0 | |
| ), O). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: filter_odd/2 | |
| TEXTUAL DECRIPTION: finds the odd numbers in a list | |
| QUERIES & ANSWERS: | |
| ?- filter_odd([-2, 4, 3, 8, 1], P). | |
| P = [3, 1]. | |
| ----------------------------------------------------------------------------*/ | |
| filter_odd(L, O) :- | |
| findall(X, ( | |
| member(X, L), | |
| M is X mod 2, | |
| M is 1 | |
| ), O). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: write_list_head/1 | |
| TEXTUAL DECRIPTION: writes the head of a list and recurses onto the tail (perhaps poorly named) | |
| QUERIES & ANSWERS: | |
| ?- write_list_head([4]). | |
| 4 | |
| true . | |
| ?- write_list_head([4, 3]). | |
| 4, 3 | |
| true . | |
| ----------------------------------------------------------------------------*/ | |
| write_list_head([]). | |
| write_list_head([H]) :- | |
| write(H). | |
| write_list_head([H|T]) :- | |
| write(H), | |
| write(', '), | |
| write_list_head(T). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: write_list/1 | |
| TEXTUAL DECRIPTION: writes a list | |
| QUERIES & ANSWERS: | |
| ?- write([4]). | |
| [4] | |
| true . | |
| ?- write_list([4, 3]). | |
| [4, 3] | |
| true . | |
| ----------------------------------------------------------------------------*/ | |
| write_list(L) :- | |
| write('['), | |
| write_list_head(L), | |
| write(']'). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: averages/2 | |
| TEXTUAL DECRIPTION: main entry point to the program, filters positive numbers, | |
| then out of those, filters the even numbers and prints them and averages them, | |
| then does the same with odd. finally returns a list of two average terms, each | |
| one containing the average and whether it is the even or odd numbers | |
| QUERIES & ANSWERS: | |
| ?- averages([1,2,3,4], O). | |
| Evens that will be averaged: [2, 4] | |
| Odds that will be averaged: [1, 3] | |
| O = [average(3, even), average(2, odd)] . | |
| ?- averages([3,1,4,8,9,13,51], O). | |
| Evens that will be averaged: [4, 8] | |
| Odds that will be averaged: [3, 1, 9, 13, 51] | |
| O = [average(6, even), average(15.4, odd)] . | |
| ----------------------------------------------------------------------------*/ | |
| averages(L, O) :- | |
| filter_positive(L, Positives), | |
| % evens | |
| filter_even(Positives, Evens), | |
| write('Evens that will be averaged: '), | |
| write_list(Evens), | |
| nl, | |
| avg(Evens, AvgEvens), | |
| % odds | |
| filter_odd(Positives, Odds), | |
| write('Odds that will be averaged: '), | |
| write_list(Odds), | |
| nl, | |
| avg(Odds, AvgOdds), | |
| O = [average(AvgEvens, even), average(AvgOdds, odd)]. | |
| /*---------------------------------------------------------------------------- | |
| EXERCISE NUMBER: 6 | |
| ----------------------------------------------------------------------------*/ | |
| ?-consult('SentenceToListOfLettersOrWords.pl'). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: transposition/2 | |
| TEXTUAL DECRIPTION: detects a transposition error in a word and finds the | |
| correct word | |
| QUERIES & ANSWERS: | |
| ?- transposition([t,a,b,e,l], C). | |
| C = [t, a, b, l, e] . | |
| ADDITIONAL COMMENTS: Assumption: the two letters are next to eachother. This | |
| means that if we swap the first with the last letter like table -> eablt, this | |
| doesn't count. This made this check much easier to implement. | |
| ----------------------------------------------------------------------------*/ | |
| transposition(I, C) :- | |
| not(word(I)), | |
| word(C), | |
| % A : first letter (in correct word) | |
| % B : second letter (in correct word) | |
| % model the correct word, particularly | |
| % 1) part before [A, B] | |
| % 2) [A, B] | |
| % 3) part after [A, B] | |
| append(Before, [A, B|After], C), | |
| % model the incorrect word, particularly | |
| % 1) part before A | |
| % 2) part where A and B are swapped ([B, A]) | |
| % 3) part after B | |
| append(Before, [B, A|After], I). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: wrong_letter/2 | |
| TEXTUAL DECRIPTION: detects a wrong letter error in a word and finds the | |
| correct word | |
| QUERIES & ANSWERS: | |
| ?- wrong_letter([f,a,b,l,e], C). | |
| C = [t, a, b, l, e] . | |
| ----------------------------------------------------------------------------*/ | |
| wrong_letter(I, C) :- | |
| not(word(I)), | |
| word(C), | |
| % WWL : word without letter (should exist in both I and C) | |
| select(_, I, WWL), | |
| select(_, C, WWL). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: extra_letter/2 | |
| TEXTUAL DECRIPTION: detects an exrta letter error in a word and finds the | |
| correct word | |
| QUERIES & ANSWERS: | |
| ?- extra_letter([t,a,b,l,e,l], C). | |
| C = [t, a, b, l, e] . | |
| ----------------------------------------------------------------------------*/ | |
| extra_letter(I, C) :- | |
| not(word(I)), | |
| word(C), | |
| select(_, I, C). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: word/1 | |
| TEXTUAL DECRIPTION: defines a word as a fact so it can be used by the error | |
| checkers. | |
| ----------------------------------------------------------------------------*/ | |
| word([t, a, b, l, e]). | |
| word([m, a, t, h, s]). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: check_word/1 | |
| TEXTUAL DECRIPTION: checks a word for an error and prints the result. this is | |
| defined four times, one for each of the error types we have, and one as a | |
| fallback of sorts | |
| QUERIES & ANSWERS: | |
| ?- check_word([t,a,b,e,l]). | |
| transposition of two letters (correct: [t,a,b,l,e]) | |
| true . | |
| ?- check_word([f,a,b,l,e]). | |
| wrong letter (correct: [t,a,b,l,e]) | |
| true . | |
| ?- check_word([t,a,b,l,e,l]). | |
| extra letter (correct: [t,a,b,l,e]) | |
| true . | |
| ----------------------------------------------------------------------------*/ | |
| check_word(W) :- | |
| transposition(W, C), | |
| write('transposition of two letters (correct: '), | |
| write(C), | |
| write(')'). | |
| check_word(W) :- | |
| wrong_letter(W, C), | |
| write('wrong letter (correct: '), | |
| write(C), | |
| write(')'). | |
| check_word(W) :- | |
| extra_letter(W, C), | |
| write('extra letter (correct: '), | |
| write(C), | |
| write(')'). | |
| check_word(W) :- | |
| not(transposition(W, _)), | |
| not(wrong_letter(W, _)), | |
| not(extra_letter(W, _)), | |
| write('unknown word'). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: check_words/2 | |
| TEXTUAL DECRIPTION: checks a list of words for the issues recursively | |
| QUERIES & ANSWERS: | |
| ?- check_words([[t,a,b,l,e], [t,a,b,e,l], [t,a,b,l,e,l], [ta,b,i,e]]). | |
| [t,a,b,l,e]: unknown word | |
| [t,a,b,e,l]: transposition of two letters (correct: [t,a,b,l,e]) | |
| [t,a,b,l,e,l]: extra letter (correct: [t,a,b,l,e]) | |
| [ta,b,i,e]: unknown word | |
| false. | |
| ----------------------------------------------------------------------------*/ | |
| check_words([H|T]) :- | |
| write(H), | |
| write(': '), | |
| check_word(H), | |
| !, % the reason we cut here is because for some cases, for example, when | |
| % there's a transposition, this also counts as a wrong letter, but we don't | |
| % want it to. nevertheless it gets checked and the error is printed without | |
| % the cut. having the cut here essentially only performs the first check. | |
| % of course, it requires the predicates to be defined in a specific order | |
| % (depending on the priority of each check. I think the one I have is | |
| % decent.) | |
| nl, | |
| check_words(T). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: check_sentence/2 | |
| TEXTUAL DECRIPTION: checks a sentence given a a string for errors and prints the result for each word | |
| QUERIES & ANSWERS: | |
| % transposition | |
| ?- check_sentence('the book is on the tabel'). | |
| [t,h,e]: unknown word | |
| [b,o,o,k]: unknown word | |
| [i,s]: unknown word | |
| [o,n]: unknown word | |
| [t,h,e]: unknown word | |
| [t,a,b,e,l]: transposition of two letters (correct: [t,a,b,l,e]) | |
| false. | |
| % transsposition (twice) | |
| ?- check_sentence('the book is on the atbel'). | |
| [t,h,e]: unknown word | |
| [b,o,o,k]: unknown word | |
| [i,s]: unknown word | |
| [o,n]: unknown word | |
| [t,h,e]: unknown word | |
| [a,t,b,e,l]: unknown word | |
| false. | |
| % wrong letter | |
| ?- check_sentence('the book is on the tabie'). | |
| [t,h,e]: unknown word | |
| [b,o,o,k]: unknown word | |
| [i,s]: unknown word | |
| [o,n]: unknown word | |
| [t,h,e]: unknown word | |
| [t,a,b,i,e]: wrong letter (correct: [t,a,b,l,e]) | |
| false. | |
| % two unknown letters | |
| ?- check_sentence('the book is on the feble'). | |
| [t,h,e]: unknown word | |
| [b,o,o,k]: unknown word | |
| [i,s]: unknown word | |
| [o,n]: unknown word | |
| [t,h,e]: unknown word | |
| [f,e,b,l,e]: unknown word | |
| false. | |
| % extra letter | |
| ?- check_sentence('the book is on the tablel'). | |
| [t,h,e]: unknown word | |
| [b,o,o,k]: unknown word | |
| [i,s]: unknown word | |
| [o,n]: unknown word | |
| [t,h,e]: unknown word | |
| [t,a,b,l,e,l]: extra letter (correct: [t,a,b,l,e]) | |
| false. | |
| % two extra letters | |
| ?- check_sentence('the book is on the ltablel'). | |
| [t,h,e]: unknown word | |
| [b,o,o,k]: unknown word | |
| [i,s]: unknown word | |
| [o,n]: unknown word | |
| [t,h,e]: unknown word | |
| [l,t,a,b,l,e,l]: unknown word | |
| false. | |
| % all of them | |
| ?- check_sentence('tabel atbel tabie feble tablel ltablel'). | |
| [t,a,b,e,l]: transposition of two letters (correct: [t,a,b,l,e]) | |
| [a,t,b,e,l]: unknown word | |
| [t,a,b,i,e]: wrong letter (correct: [t,a,b,l,e]) | |
| [f,e,b,l,e]: unknown word | |
| [t,a,b,l,e,l]: extra letter (correct: [t,a,b,l,e]) | |
| [l,t,a,b,l,e,l]: unknown word | |
| false. | |
| ----------------------------------------------------------------------------*/ | |
| check_sentence(S) :- | |
| string_to_listofwords(S, W), | |
| !, % cut, because we only want to get the first result | |
| % (string_to_listofwords is weirdly written and produces a million results) | |
| check_words(W). | |
| /*---------------------------------------------------------------------------- | |
| EXERCISE NUMBER: 7 | |
| ----------------------------------------------------------------------------*/ | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: alphabet/1 | |
| TEXTUAL DECRIPTION: defines the alphabet for other predicates to reference. | |
| ----------------------------------------------------------------------------*/ | |
| alphabet(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: letter/2 | |
| TEXTUAL DECRIPTION: assocaites a letter with its index in the alphabet (1-indexed) | |
| QUERIES & ANSWERS: | |
| ?- letter('f', Idx). | |
| Idx = 6. | |
| ?- letter(L, 6). | |
| L = f. | |
| ----------------------------------------------------------------------------*/ | |
| letter('a', 1). | |
| letter('b', 2). | |
| letter('c', 3). | |
| letter('d', 4). | |
| letter('e', 5). | |
| letter('f', 6). | |
| letter('g', 7). | |
| letter('h', 8). | |
| letter('i', 9). | |
| letter('j', 10). | |
| letter('k', 11). | |
| letter('l', 12). | |
| letter('m', 13). | |
| letter('n', 14). | |
| letter('o', 15). | |
| letter('p', 16). | |
| letter('q', 17). | |
| letter('r', 18). | |
| letter('s', 19). | |
| letter('t', 20). | |
| letter('u', 21). | |
| letter('v', 22). | |
| letter('w', 23). | |
| letter('x', 24). | |
| letter('y', 25). | |
| letter('z', 26). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: find_letters/4 | |
| TEXTUAL DECRIPTION: given an input alphabet (first argument), a letter (second | |
| argument), higher/lower (third argument), return (to the fourth argument) the | |
| sub-list of the given alphabet of letters that are after (if given higher) or | |
| before (of given lower) the given letter. | |
| QUERIES & ANSWERS: | |
| ?- alphabet(A), filter_letters(A, 'f', higher, O). | |
| A = [a, b, c, d, e, f, g, h, i|...], | |
| O = [g, h, i, j, k, l, m, n, o|...] ; | |
| false. | |
| ?- alphabet(A), filter_letters(A, 'f', lower, O). | |
| A = [a, b, c, d, e, f, g, h, i|...], | |
| O = [a, b, c, d, e]. | |
| ADDITIONAL COMMENTS: 1) I think it can also be implemented using append (and | |
| it sounds like it'd be faster) but this feels more intuitive, 2) I am not sure | |
| why on the first query above, it shows false. That happens. It doesn't seem to | |
| cause issues though. | |
| ----------------------------------------------------------------------------*/ | |
| filter_letters(IA, L, higher, OA) :- | |
| letter(L, LIdx), | |
| findall(X, ( | |
| member(X, IA), | |
| letter(X, XIdx), | |
| XIdx > LIdx | |
| ), OA). | |
| filter_letters(IA, L, lower, OA) :- | |
| letter(L, LIdx), | |
| findall(X, ( | |
| member(X, IA), | |
| letter(X, XIdx), | |
| XIdx < LIdx | |
| ), OA). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: element_at/3 | |
| TEXTUAL DECRIPTION: searches in a list for an element at a given index | |
| QUERIES & ANSWERS: | |
| ?- element_at([0,1,2,3,4], Idx, 4). | |
| Idx = 4 . | |
| ?- element_at([0,1,2,3,4], 4, E). | |
| E = 4 . | |
| ADDITIONAL COMMENTS: There is probably a built in predicate that does this but | |
| I don't know it | |
| ----------------------------------------------------------------------------*/ | |
| element_at(L, Idx, E) :- | |
| % indexing starts from 0 | |
| element_at(L, Idx, 0, E). | |
| % CIdx: Current index | |
| element_at([_|T], Idx, CIdx, E) :- | |
| NIdx is CIdx + 1, | |
| element_at(T, Idx, NIdx, E). | |
| % essentially if Idx = CIdx then we bind E (last argument) to the head and don't | |
| % recurse because we've completed our search | |
| element_at([H|_], Idx, Idx, H). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: divide/3 | |
| TEXTUAL DECRIPTION: given an alphabet and a guess that has just been made, | |
| prompts the user about whether their letter is higher or lower than the guess, | |
| and filters the alphabet accordingly and calls back to guess | |
| ----------------------------------------------------------------------------*/ | |
| % A: current alphabet | |
| % G: previously made guess | |
| % NG: amount of gueses | |
| divide(A, G, NG) :- | |
| repeat, | |
| write('Is it higher or lower?'), | |
| read(I), | |
| (I='higher' -> filter_letters(A, G, higher, NA) | |
| ;I='lower' -> filter_letters(A, G, lower, NA) | |
| ;I=_ -> fail % re-ask if the answer is neither so we can get an appropriate response | |
| ), | |
| guess(NA, NG). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: guess/2 | |
| TEXTUAL DECRIPTION: given an alphabet, guesses the letter in the middle and | |
| adjusts the alphabet and recurses if the guess was wrong, or stops if it was | |
| right, all while keeping track of the amount of guesse | |
| QUERIES & ANSWERS: | |
| ?- alphabet(A), guess(A, 0). | |
| Guess: n | |
| Is it right? [y/n] | |
| |: y. | |
| :) | |
| Found in 1 guesses | |
| A = [a, b, c, d, e, f, g, h, i|…] . | |
| ?- alphabet(A), guess(A, 0). | |
| Guess: n | |
| Is it right? [y/n] | |
| |: n. | |
| Is it higher or lower?|: higher. | |
| Guess: u | |
| Is it right? [y/n] | |
| |: n. | |
| Is it higher or lower?|: lower. | |
| Guess: r | |
| Is it right? [y/n] | |
| |: y. | |
| :) | |
| Found in 3 guesses | |
| A = [a, b, c, d, e, f, g, h, i|…] . | |
| ----------------------------------------------------------------------------*/ | |
| % A: current alphabet | |
| % NG: number of guesses | |
| guess(A, NG) :- | |
| % next number of guesses (the one we'll be using from now on, since we are | |
| % making a guess and it's increased) | |
| NNG is NG + 1, | |
| % find the letter in the middle of the alphabet that we have | |
| % | |
| % MIdx: index of middle element | |
| % M: value of middle element (the guess) | |
| length(A, L), | |
| MIdx is L // 2, % <-- integer division, since, for example, on the second | |
| % guess where our alphabet consists of 13 letters, the middle would be at index | |
| % 6.5 | |
| element_at(A, MIdx, M), | |
| write('Guess: '), | |
| write(M), | |
| nl, | |
| repeat, | |
| write('Is it right? [y/n]'), | |
| nl, | |
| read(I), | |
| (I='y' -> write(':)'), nl, write('Found in '), write(NNG), write(' guesses'), nl | |
| ;I='n' -> divide(A, M, NNG) | |
| ;I=_ -> fail % re-ask if the answer is neither so we can get an appropriate response | |
| ). | |
| guess() :- | |
| alphabet(A), | |
| guess(A, 0). | |
| /*---------------------------------------------------------------------------- | |
| EXERCISE NUMBER: 8 | |
| ----------------------------------------------------------------------------*/ | |
| action(movedown):- | |
| robot((X,Y)), | |
| Y1 is Y-1, | |
| valid_free_move((X,Y1)), | |
| update(robot((X,Y)),robot((X,Y1)),[movedown]),!. | |
| action(moveleft):- | |
| robot((X,Y)), | |
| X1 is X-1, | |
| valid_free_move((X1,Y)), | |
| update(robot((X,Y)),robot((X1,Y)),[moveleft]),!. | |
| action(moveright):- | |
| robot((X,Y)), | |
| X1 is X+1, | |
| valid_free_move((X1,Y)), | |
| update(robot((X,Y)),robot((X1,Y)),[moveright]),!. | |
| action(pushup):- | |
| robot((X,Y)), | |
| Y1 is Y+1, | |
| box((X,Y1)), | |
| Y2 is Y1+1, | |
| valid_push((X,Y2)), | |
| update(robot((X,Y)),robot((X,Y1)),[pushup]), | |
| update(box((X,Y1)),box((X,Y2)),[]),!. | |
| % assert is used for 'creating' facts and retract for 'deleting' them. they are | |
| % used because the state of the game is stored using facts, such as: | |
| % box/1 for the position of the box | |
| % obstacle/1 for the position of obstacles | |
| % robot/1 for the position of the robot | |
| % | |
| % these facts dynamically change as the game progresses, so for example when | |
| % updating the box's position we retract the fact about the previous position | |
| % and assert the new one | |
| /*---------------------------------------------------------------------------- | |
| EXERCISE NUMBER: 9:a | |
| ----------------------------------------------------------------------------*/ | |
| % The predicate finds the smallest number in a list of numbers. | |
| /*---------------------------------------------------------------------------- | |
| EXERCISE NUMBER: 9:b | |
| ----------------------------------------------------------------------------*/ | |
| % | --------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | | |
| % | | Ascending Order | Descending Order | Random Order | | |
| % | | 25 Elements | 25 Elements | 25 Elements | | |
| % | --------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | | |
| % | Predicate | cpu time | inferences | cpu time | inferences | cpu time | inferences | | |
| % | --------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | | |
| % | p1 | 4.9999999873762135e-06 | 10 | 5.282055999999955 | 100663292 | 3.8035730000000285 | 74883076 | | |
| % | p2 | 5.999999984851456e-06 | 14 | 3.999999989900971e-06 | 98 | 3.999999989900971e-06 | 92 | | |
| % | p3 | 1.9999999949504854e-06 | 19 | 2.999999992425728e-06 | 75 | 2.999999992425728e-06 | 96 | | |
| % | p4 | 1.9999999949504854e-06 | 15 | 1.9999999949504854e-06 | 51 | 1.9999999949504854e-06 | 71 | | |
| % | p5 | 1.9999999949504854e-06 | 14 | 2.999999992425728e-06 | 50 | 3.999999989900971e-06 | 71 | | |
| % | p6 | 1.9999999949504854e-06 | 14 | 4.9999999873762135e-06 | 98 | 3.999999989900971e-06 | 77 | | |
| % | p7 | 6.000000041694875e-06 | 17 | 3.700000002027082e-05 | 777 | 1.6000000016447302e-05 | 115 | | |
| % | p8 | 1.1000000029071089e-05 | 24 | 5.000000044219632e-06 | 64 | 5.000000044219632e-06 | 64 | | |
| % | p9 | 1.0000000031595846e-05 | 35 | 1.8000000011397788e-05 | 155 | 2.2999999998774e-05 | 155 | | |
| % | --------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | | |
| % | |
| % I think p4 is the most efficient one because, by visually looking at the | |
| % table, it seems to have a constant, relatively low (though not the lowest) | |
| % cpu time across orders. Same with the inferences | |
| /*---------------------------------------------------------------------------- | |
| EXERCISE NUMBER: 9:c | |
| ----------------------------------------------------------------------------*/ | |
| % | --------- | ------------------ | ------------- | ------ | | |
| % | Predicate | Easy to understand | Easy to write | Purity | | |
| % | --------- | ------------------ | ------------- | ------ | | |
| % | p1 | 3 | 4 | 5 | | |
| % | p2 | 4 | 4 | 5 | | |
| % | p3 | 2 | 2 | 5 | | |
| % | p4 | 2 | 2 | 5 | | |
| % | p5 | 3 | 3 | 5 | | |
| % | p6 | 4 | 4 | 5 | | |
| % | p7 | 2 | 3 | 4 | | |
| % | p8 | 2 | 2 | 4 | | |
| % | p9 | 2 | 2 | 2 | | |
| % | --------- | ------------------ | ------------- | ------ | | |
| /*---------------------------------------------------------------------------- | |
| EXERCISE NUMBER: 10 | |
| ----------------------------------------------------------------------------*/ | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: folder/1 | |
| TEXTUAL DECRIPTION: checks if a constnat is a folder | |
| ----------------------------------------------------------------------------*/ | |
| folder(root). | |
| folder(usr). | |
| folder(bin). | |
| folder(lib). | |
| folder(share). | |
| folder(etc). | |
| folder(proc). | |
| folder(tty). | |
| folder(sys). | |
| folder(devices). | |
| folder(dev). | |
| folder(boot). | |
| folder(home). | |
| folder(alex). | |
| folder(docs). | |
| folder(code). | |
| folder(prolog). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: file/1 | |
| TEXTUAL DECRIPTION: checks if a constant is a file | |
| ----------------------------------------------------------------------------*/ | |
| file(cat). | |
| file(ls). | |
| file(sh). | |
| file(passwd). | |
| file(random). | |
| file(urandom). | |
| file(null). | |
| file(zero). | |
| file('10.pl'). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: contains/2 | |
| TEXTUAL DECRIPTION: gets the list of folders or files contained in a folder | |
| ----------------------------------------------------------------------------*/ | |
| % folders | |
| contains(root, [usr, etc, proc, sys, dev, boot, home]). | |
| contains(usr, [bin, lib, share]). | |
| contains(etc, []). | |
| contains(proc, [tty]). | |
| contains(sys, [devices]). | |
| contains(dev, []). | |
| contains(boot, []). | |
| contains(home, [alex]). | |
| contains(alex, [docs]). | |
| contains(alex, [code]). | |
| contains(code, [prolog]). | |
| % files | |
| contains(bin, [cat, ls, sh]). | |
| contains(etc, [passwd]). | |
| contains(dev, [random, urandom, null, zero]). | |
| contains(prolog, ['10.pl']). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: path/2 | |
| TEXTUAL DECRIPTION: finds a path to a file, starting by the root | |
| ----------------------------------------------------------------------------*/ | |
| path(File, Path) :- | |
| path(root, File, Path). | |
| /*---------------------------------------------------------------------------- | |
| PREDICATE: path/3 | |
| TEXTUAL DECRIPTION: finds a path to a file, starting by a given parent folder | |
| ----------------------------------------------------------------------------*/ | |
| path(Parent, File, [Parent]) :- | |
| file(File), | |
| contains(Parent, Contained), | |
| member(File, Contained). | |
| path(Parent, File, [Parent | Rest]) :- | |
| folder(Parent), | |
| file(File), | |
| contains(Parent, Contained), | |
| not(member(File, Contained)), | |
| member(Intermediate, Contained), | |
| path(Intermediate, File, Rest). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment