diff --git a/polimani.pl b/polimani.pl index eedd134..cce9b39 100644 --- a/polimani.pl +++ b/polimani.pl @@ -2,11 +2,17 @@ %% Follows 'Coding guidelines for Prolog' - Theory and Practice of Logic Programming %% https://doi.org/10.1017/S1471068411000391 +%% Import the Constraint Logic Programming over Finite Domains lybrary +%% Essentially, this library improves the way Prolog deals with integers, +%% allowing more predicates to be reversible. +%% For instance, number(N) is always false, which prevents the +%% reversing of a predicate. +:- use_module(library(clpfd)). + %% polynomial_variable_list(-List:atom) is det % % List of possible polynomial variables % - polynomial_variable_list([x, y, z]). %% polynomial_variable(?X:atom) is det @@ -16,37 +22,75 @@ polynomial_variable_list([x, y, z]). polynomial_variable(X) :- polynomial_variable_list(V), member(X, V). -polynomial_variable(P) :- - polynomial_variable_list(V), - member(X, V), - P = X^_. +%% polynomial_variable(P) :- +%% polynomial_variable_list(V), +%% member(X, V), +%% P = X^N, +%% N == 1. %% Tests: %% ?- polynomial_variable(x). %@ true . +%% ?- polynomial_variable(x^(1)). +%@ false. -%% power(+X:atom) is det +%% power(+X:atom) is semidet % % Returns true if X is a power term, false otherwise. +% Fully reversible. % -power(X ^ N) :- - %% X ^ N = P, - integer(N), - !, - %% write(N), - N >= 1, - polynomial_variable(X), - !. +power(P) :- + %% Makes this more reversible + P = X ^ N, + %% CPL(FD) library predicate to perform integer comparassions in a reversible way + %% If 0 > N succeds, fail, otherwise check if X is a valid variable + (zcompare((>), 0, N); polynomial_variable(X)), fail. + %% if(zcompare((>), 0, N), + %% fail, + %% polynomial_variable(X) + %% ). power(X) :- - polynomial_variable(X), - !. + polynomial_variable(X). %% Tests: +%% ?- power(x). +%@ true . %% ?- power(x^1). %@ true . +%% ?- power(x^3). +%@ false. +%@ false. +%@ false. +%@ true . +%@ true . %% ?- power(x^(-3)). %@ false. -%@ true. -%@ -3 +%@ false. %@ true . +%@ false. +%@ true . +%@ false. +%% ?- power(X). +%@ X = x ; +%@ X = y ; +%@ X = z. + +%% if(+P, -T, -F) is det +% +% A simple implementation of an if predicate. +% Returns T if P is true +% or F if P otherwise +% +%% if(If_1, Then_0, Else_0) :- +%% call(If_1, T), +%% ( T == true -> call(Then_0) +%% ; T == false -> call(Else_0) +%% ; nonvar(T) -> throw(error(type_error(boolean,T),_)) +%% ; /* var(T) */ throw(error(instantiation_error,_)) +%% ). +if(P, T, F) :- (P == true, T); F. +%% ?- if(true, N = 1, N = 2). +%@ N = 1 . +%% ?- if(false, N = 1, N = 2). +%@ N = 2. %% term(+N:atom) is det % @@ -63,6 +107,8 @@ term(L * R) :- %% ?- term(2*x^3). %@ true . %% ?- term(x^(-3)). +%@ false. +%% ?- term((-3)*x^2). %@ true . %% is_term_valid_in_predicate(+T, +F) is det @@ -95,22 +141,37 @@ polynomial(L + R) :- polynomial(L), term(R). %% Tests: -%% TODO +%% ?- polynomial(x). +%@ true . +%% ?- polynomial(x^3). +%@ true . +%% ?- polynomial(3*x^7). +%@ true . +%% ?- polynomial(2 + 3*x + 4*x*y^3). +%@ true . %% power_to_canon(+T:atom, -T^N:atom) is det % % Returns a canon power term. % power_to_canon(T^N, T^N) :- - polynomial_variable(T). + polynomial_variable(T), + %% N \= 1. + ( + zcompare(=, 1, N) + ; + true + ). power_to_canon(T, T^1) :- polynomial_variable(T). %% Tests: %% ?- power_to_canon(x, X). -%@ X = x^1. -%% ?- power_to_canon(X, X^1). +%@ X = x^1 . +%% ?- power_to_canon(X, x^1). %@ X = x . -%@ X = x. +%@ X = x . +%% ?- power_to_canon(X, x^4). +%@ X = x^4 . %% term_to_list(?T, ?List) is det % @@ -132,12 +193,12 @@ term_to_list(P, [P2]) :- %% Tests: %% ?- term_to_list(1*2*y*z*23*x*y*x^3*x, X). %@ X = [x^1, x^3, y^1, x^1, 23, z^1, y^1, 2, 1] . -%@ X = [x^1, x^3, y^1, x^1, 23, z^1, y^1, 2] . %% ?- term_to_list(X, [y^1, x^1]). %@ X = x*y . %% ?- term_to_list(X, [x^4]). -%@ X = x^4 . %@ false. +%@ false. +%@ X = x^4 . %% ?- term_to_list(X, [y^6, z^2, x^4]). %@ X = x^4*z^2*y^6 .