Merge pull request #1 from diogogithub/reversible

Fix some serious bugs
This commit is contained in:
Diogo Cordeiro 2018-11-22 12:36:37 +00:00 committed by GitHub
commit 441a1089c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 84 additions and 25 deletions

View File

@ -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,73 @@ 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^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(P)); 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 +105,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 +139,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 +191,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 .