Giter Club home page Giter Club logo

projog's People

Contributors

dependabot[bot] avatar s-webber avatar stephen-w avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

projog's Issues

Configure arithmetic functions by both name and arity.

Currently arithmetic functions are configured using just their name (e.g. +, - and *).

For higher granularity, and to be consistent with predicates, arithmetic functions could be configured by a combination of both their name and arity (i.e. number of arguments they accept).

e.g.: -/2 (i.e. subtraction) and -/1 (i.e. minus)

add "findall" built-in predicate

findall/3 provides a single list containing all solutions to the specified goal.

Example:

?- findall(Y, (member(X,[6,3,7,2,5,4,3]), X<4, Y is X*X), L).
L = [9, 4, 9].

Reduce boiler-plate required to add new predicates.

The current pattern for implementing new predicates is to implement public boolean evaluate(Term... args) of Predicate.

For performance reasons (to avoid the overhead of compiled predicates having to create a new Term[] every time they call evaluate) it is also common practice for predicates to create an overloaded version which accepts the exact number of arguments required - that the evaluate(Term...) varargs version (which is still used in interpreted, rather than compiled, mode) then delegates to.

Example:

public class SingletonPredicateExample extends AbstractSingletonPredicate {
   @Override
   public boolean evaluate(Term... args) {
      return evaluate(args[0]);
   }

   /**
    * Overloaded version of {@link #evaluate(Term...)} that avoids the overhead of creating a new {@code Term} array.
    * 
    * @see org.projog.core.Predicate#evaluate(Term...)
    */
   public boolean evaluate(Term arg) {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
      String currentDate = sdf.format(new Date());
      return arg.unify(new Atom(currentDate));
   }
}

It would be more convenient if it was possible to just create an overloaded version of evaluate that accepts the exact number of arguments that the predicate requires. (i.e. Don't implement the varargs version each time.)

e.g. public boolean evaluate() (for a predicate that does not accept any arguments - e.g. true) or public boolean evaluate(Term arg1, Term arg2, Term arg3) (for a predicate that accepts 3 arguments - e.g. bagof/3)

add keysort/2 built-in predicate

First argument is a list of key/value pairs represented using a hypen (i.e. -) as the functor (e.g. key-value).
Predicate will sort list by key of pairs and unify result with second argument.

Example use:

?- keysort([a - 1,b - 3,c - 2], X).
X = [a-1, b-3, c-2].

?- keysort([c - 2,a - 1, b - 3], X).
X = [a-1, b-3, c-2].

support not/1 (alternative to the existing \+ built-in predicate)

not is a synonym for the existing \+ predicate.

It would be convenient if both not and \+ were supported by Projog (providing the same functionality).

Currently supported:

?- \+ true.
false.

?- \+ false.
true.

Currently unsupported:

?- not(true).
false.

?- not(false).
true.

arithmetic function / incorrectly behaves like // for integer numbers

When being called with two integer arguments the / arithmetic function currently behaves in the same way as the // function (see #25) does - this is incorrect when the exact result is not an integer.

Current (incorrect) behaviour:

?- X is 6 / 2.
X = 3.
?- X is 7 / 2.
X = 3.

Correct behaviour:

?- X is 6 / 2.
X = 3.
?- X is 7 / 2.
X = 3.5.

add delete/3 built-in predicate

Attempts to unify the third argument with a version of the list represented by the first argument with any occurrences of the second argument removed.

Examples:

?- delete([h,e,l,l,o], l, X).
X = [h, e, o].

?- delete([h,e,l,l,o], X, Y).
Y = [].

?- X=p(A,b,e), delete([p(_,_,_),p(a,B,c),p(q,B,e),p(z,b,W)], X, Y).
X = p(A, b, e),
Y = [p(a, B, c)].

use of variables as placeholders for predicates in conjunctions

The following query:

?- X=true, X.

Produces the following error:

Expected an atom or a predicate but got a NAMED_VARIABLE with value: X

This is not the correct behavior - the correct behavior is for the query to evaluate successfully once.

Full stacktrace:

org.projog.core.ProjogException: Expected an atom or a predicate but got a NAMED_VARIABLE with value: X
        at org.projog.core.PredicateKey.createForTerm(PredicateKey.java:58)
        at org.projog.core.KnowledgeBase.getPredicateFactory(KnowledgeBase.java:199)
        at org.projog.core.function.compound.Conjunction.getPredicate(Conjunction.java:174)
        at org.projog.core.function.compound.Conjunction.getPredicate(Conjunction.java:163)
        at org.projog.core.function.compound.Conjunction.getPredicate(Conjunction.java:139)
        at org.projog.api.QueryResult.next(QueryResult.java:70)
        at org.projog.tools.ProjogConsole.evaluateOnce(ProjogConsole.java:183)
        at org.projog.tools.ProjogConsole.parseAndExecute(ProjogConsole.java:121)
        at org.projog.tools.ProjogConsole.run(ProjogConsole.java:75)
        at org.projog.tools.ProjogConsole.main(ProjogConsole.java:222)

add sort/2 built-in predicate

True if a sorted version of list represented by the first argument can be unified with the second argument.

NOTE: Similar to msort/2 (see #50) - but, unlike msort/2, sort/2 does remove duplicates.

Example:

?- sort([q,w,e,r,t,y],X).
X = [e, q, r, t, w, y].

?- sort([h,e,l,l,o],X).
X = [e, h, l, o].

add integer/1 built-in predicate

integer(X) is true when X is bound to an integer, else false.

Examples:

?- integer(0).
true.

?- integer(1).
true.

?- integer(-1).
true.

?- integer(76832).
true.

?- integer(1.0).
false.

?- integer("1").
false.

?- integer(1+1).
false.

add length/2 built-in predicate

length(X,Y) is true when the integer Y is equal to the number of elements in list Y

Example use:

?- length([a,b,c],X).
X = 3.

?- length([],X).
X = 0.

add member/2 built-in predicate

member(E, L) succeeds if E is a member of the list L.

Unlike "memberchk(E, L)", an attempt is made to retry the goal during backtracking - so it can be used to enumerate the members of a list.

Example use:

?- member(a,[a,b,c]).
true .

?- member(b,[a,b,c]).
true ;
false.

?- member(a,[a,b,c]).
true ;
false.

?- member(b,[a,b,c]).
true ;
false.

?- member(c,[a,b,c]).
true.

?- member(d,[a,b,c]).
false.

?- member(X,[a,b,c]).
X = a ;
X = b ;
X = c.

?- member(a,[a,a,a]).
true ;
true ;
true.

add ** arithmetic function

The ** arithmetic function calculates the first argument raised to the power of the second argument.

Examples:

?- X is 2**5.
X = 32.

?- X is 5**3.
X = 125.

add atom_concat/3 built-in predicate

atom_concat(X, Y, Z) attempts to unify Z with the concatenation of X and Y

Examples:

Final argument is a variable:

?- atom_concat(abc, def, X).
X = abcdef.

One of the first two arguments is a variable:

?- atom_concat(abc, X, abcdef).
X = def.

?- atom_concat(X, def, abcdef).
X = abc.

Both of the first two arguments are variables:

40 ?- atom_concat(X, Y, abc).
X = '',
Y = abc ;
X = a,
Y = bc ;
X = ab,
Y = c ;
X = abc,
Y = ''.

add append/3 built-in predicate

Example use:

?- append(X, Y, [1,2,3,4]).
X = [],
Y = [1, 2, 3, 4] ;
X = [1],
Y = [2, 3, 4] ;
X = [1, 2],
Y = [3, 4] ;
X = [1, 2, 3],
Y = [4] ;
X = [1, 2, 3, 4],
Y = [] ;
false.

?- append([1,2],[3,4],[1,2,3,4]).
true.

 ?- append([1,2],[3,4],Z).
Z = [1, 2, 3, 4].

?- append([1,2|q],[3,4],Z).
false.

?- append([1,2],[3,4|y],Z).
Z = [1, 2, 3, 4|y].

Remove dependency on Write from KnowledgeBase.

Currently org.projog.core.KnowledgeBase has an instance of org.projog.core.function.io.Write as a member variable.

I think the functionality that KnowledgeBase uses Write to provide could be provided by another class.

Removing Write from KnowledgeBase would have the benefits of:

  • Reducing the responsibilities of KnowledgeBase.
  • Reducing the number of other classes KnowledgeBase relies on.

add nth0/3 built-in predicate

Add nth0/3 built-in predicate which checks the term (3rd argument) at the specified index (first argument) of the specified list (second argument).

Example use:

?- nth0(1, [h, e, l, l, o], Z).
Z = e.

?- nth0(X, [h, e, l, l, o], l).
X = 2 ;
X = 3 ;
false.

?- nth0(X, [h, e, l, l, o], z).
false.

?- nth0(X, [h, e, l, l, o], Z).
X = 0,
Z = h ;
X = 1,
Z = e ;
X = 2,
Z = l ;
X = 3,
Z = l ;
X = 4,
Z = o.

add subset/2 built-in predicate

True if first argument is a subset of the second argument.

Examples:

?- subset([a,d,e],[a,b,c,d,e,f]).
true.

?- subset([a,d,e,z],[a,b,c,d,e,f]).
false.

?- subset([a,d,e,a],[a,b,c,d,e,f]).
true.

?- subset([p(X),p(X)],[p(a),p(b),p(c)]).
X = a.

?- subset([p(a),p(b)],[p(X),p(X),p(c)]).
false.

add select/3 build-in predicate

Attempts to unify the third argument with the result of removing one instance of first argument from the list represented by the second argument.

Examples:

?- select(X,[h,e,l,l,o],Z).
X = h,
Z = [e, l, l, o] ;
X = e,
Z = [h, l, l, o] ;
X = l,
Z = [h, e, l, o] ;
X = l,
Z = [h, e, l, o] ;
X = o,
Z = [h, e, l, l] ;

?- select(l,[h,e,l,l,o],Z).
Z = [h, e, l, o] ;
Z = [h, e, l, o] ;
false.

?- select(l,[h,e,l,l,o],[h,e,l,o]).
true ;
true ;
false.

?- select(p(a,B),[p(X,q), p(a,X)],Z).
B = q,
X = a,
Z = [p(a, a)] ;
B = X,
Z = [p(X, q)] ;
false.

add msort/2 built-in predicate

True if a sorted version of list represented by the first argument can be unified with the second argument.

NOTE: Similar to sort/2 (see #42) - but, unlike sort/2, msort/2 does not remove duplicates.

Example:

?- msort([q,w,e,r,t,y],X).
X = [e, q, r, t, w, y].

?- msort([h,e,l,l,o],X).
X = [e, h, l, l, o].

Make arithmetic functions testable and documented.

Currently classes that implement built-in predicates are tested using queries contained in their comments (specified using Prolog syntax) and documented in the "Prolog Commands" section of the manual. Both the testing and documentation happen automatically as part of the Ant build process.

It would be nice if this functionality was extended to also support arithmetic functions (i.e. instances of Calculatable).

add ensure_loaded/1 built-in predicate

ensure_loaded/1 is equivalent to the existing consult/1 built-in predicate.

(In other Prolog implementations (e.g. SWI) ensure_loaded/1 does have behaviour distinct from consult/1 when dealing with module files - but as Projog does not (yet) support the concept of modules, for the time being ensure_loaded/1 can be simply a synonym for consult/1.)

add compare/3 built-in predicate

Compares second and third arguments.

  • If second is greater than third then attempts to unify first argument with >
  • If second is less than third then attempts to unify first argument with <
  • If second is equal to third then attempts to unify first argument with =

Examples:

?- compare(X, a, z).
X = (<).

?- compare(X, a, a).
X = (=).

?- compare(X, z, a).
X = (>).

?- compare(<, z, a).
false.

?- compare(>, z, a).
true.

add memberchk/2 built-in predicate

memberchk(X, Y) returns true if X is an element of the list Y

(Unlike "member(X, Y)", no attempt is made to re-evaluate during backtracking.)

Example use:

?- memberchk(a,[a,b,c]).
true.

?- memberchk(b,[a,b,c]).
true.

?- memberchk(c,[a,b,c]).
true.

?- memberchk(d,[a,b,c]).
false.

?- memberchk(a,[a,b,a,c]).
true.

?- memberchk(X,[a,b,a,c]).
X = a.

Exception retrying queries that contain a cut.

An exception is thrown when retrying queries that contain a cut (i.e. !).

Current (incorrect behaviour):

?- repeat, !.

yes (1 ms);

Caught: org.projog.core.CutException from class: org.projog.core.CutException method: <clinit> line: 22

Correct behaviour:

?- repeat, !.

yes (0 ms);

no (0 ms)

add "setof" built-in predicate

Finds solutions for the specified goal. The resulting list will be ordered using the standard ordering of terms - and will exclude duplicates. Can succeed on backtracking. Fails if the specified goal cannot be satisfied.

Example:

?- setof(Y, (member(X,[6,3,7,2,5,4,3]), X<4, Y is X*X), L).
X = 2,
L = [4] ;
X = 3,
L = [9].

add "bagof" built-in predicate

Finds solutions for the specified goal. The elements in the resulting list will appear in the order they were found and may include duplicates. Can succeed on backtracking. Fails if the specified goal cannot be satisfied.

Example:

?- bagof(Y, (member(X,[6,3,7,2,5,4,3]), X<4, Y is X*X), L).
X = 2,
L = [4] ;
X = 3,
L = [9, 9].

Exception parsing query with non-alphanumeric predicate name.

Current (incorrect) behaviour when the predicate name is the same as an infix operator:

?- X = +(1,1).

Error parsing query:
Expected . but got: ,(1, 1) after: ?-(=(X, +))
?-X = +(1,1).
           ^

Current (incorrect) behaviour when the predicate name is not the same as an infix operator:

?- X = ~(1,1).

Error parsing query:
invalid command: ~(
?-X = ~(1,1).
       ^

Correct behaviour:

?- X = +(1, 1).

X = 1 + 1

yes (0 ms)

Note: it does currently work if the predicate name is quoted (e.g. ?- X = '+'(1,1).).

Make syntax of prolog tests more concise.

As well as Java unit-tests written using JUnit, Projog also supports "system tests" written in Prolog - where queries, and their expected results, are specified in comments (i.e. prefixed by %).

These tests are located in the scripts directory and in comments contained in Java code.

An example of how these tests are constructed (taken from Call.java) is shown below:

/* SYSTEM TEST
 % %TRUE% call(true)
 % %FALSE% call(fail)
 % %QUERY% X = true, call(X)
 % %ANSWER% X = true
 % %FALSE% X = fail, call(X)

 test(a).
 test(b).
 test(c).

 % %QUERY% X = test(Y), call(X)
 % %ANSWER%
 % X = test(a)
 % Y = a
 % %ANSWER%
 % %ANSWER%
 % X = test(b)
 % Y = b
 % %ANSWER%
 % %ANSWER%
 % X = test(c)
 % Y = c
 % %ANSWER%

 testCall(X) :- call(X).

 % %FALSE% testCall(fail)
 % %TRUE% testCall(true)
 % %QUERY% testCall((true ; true))
 % %ANSWER/%
 % %ANSWER/%
 */

Is it possible to make the syntax, included in the comments used to construct these tests, more concise?

Not producing documentation for subtract/3.

The HTML documentation, generated by the build process, does not include the subtract/3 built-in predicate.

I think the problem is that there are two classes (in different packages) that have the name Subtract (one is for the arithmetic function and the other is for the list operation).

The class name (minus the package) of a document-able class is used as the file name of the corresponding HTML page. If two classes have the same name then, when the document generation process is run, the documentation of the second one found will overwrite the documentation of the first.

Include pj_add_predicate/2 in documentation.

The way that pj_add_predicate/2 is currently implemented means it is not included in the system testing or documentation processes of the Ant build script.

It would be good is this could be corrected by implementing pj_add_predicate/2 in a way that is consistent with the other built-in predicates.

get unit tests working with Java 8

When using Java 8, the testScriptGeneration test of CompiledPredicateSourceGeneratorTest fails due to:

    [junit] java.lang.RuntimeException: Comparing scripts\CompiledPredicateSourceGeneratorTest\CallCompiledEvaluatable.txt to build\org.projog.core.udp.compiler.CompiledPredicateSourceGeneratorTest\org\projog\content_generated_at_runtime\CompiledPredicate3.java caused java.lang.RuntimeException: [v0_B = _0;] in CallCompiledEvaluatable.txt not equals to [v0_C = _0;] in CompiledPredicate3.java line 27

I suspect this is due to difference in java.util.HashSet ordering between Java 8 and earlier versions.

I think the solution is to change the getVariablesToKeepTempVersionOf method of CompiledPredicateWriter to use a LinkedHashSet (so can guarantee consistent ordering regardless of Java version).

add is_list/1 built-in predicate

Example use:

?- is_list([]).
true.

is_list([a,b]).
true.

?- is_list([a|b]).
false.

?- is_list([a|[]]).
true.

?- is_list(X).
false.

use of variable as antecedant of clause

Consulting a file containing the following:

test(X) :- X.

Causes the following error:

Expected an atom or a predicate but got a NAMED_VARIABLE with value: X

Full stacktrace:

Could not read prolog source from file: test.pl due to: org.projog.core.ProjogException: Expected an atom or a predicate but got a NAMED_VARIABLE with value: X
org.projog.core.ProjogException: Expected an atom or a predicate but got a NAMED_VARIABLE with value: X
        at org.projog.core.PredicateKey.createForTerm(PredicateKey.java:58)
        at org.projog.core.KnowledgeBase.getPredicateFactory(KnowledgeBase.java:199)
        at org.projog.core.udp.interpreter.ClauseActionFactory.getClauseAction(ClauseActionFactory.java:43)
        at org.projog.core.udp.StaticUserDefinedPredicateFactory.createClauseActionsFromClauseModels(StaticUserDefinedPredicateFactory.java:115)
        at org.projog.core.udp.StaticUserDefinedPredicateFactory.setCompiledPredicateFactory(StaticUserDefinedPredicateFactory.java:101)
        at org.projog.core.udp.StaticUserDefinedPredicateFactory.compile(StaticUserDefinedPredicateFactory.java:94)
        at org.projog.core.ProjogSourceReader.addUserDefinedPredicatesToKnowledgeBase(ProjogSourceReader.java:227)
        at org.projog.core.ProjogSourceReader.parse(ProjogSourceReader.java:147)
        at org.projog.core.ProjogSourceReader.parseFile(ProjogSourceReader.java:59)
        at org.projog.api.Projog.consultFile(Projog.java:158)
        at org.projog.tools.ProjogConsole.consultScript(ProjogConsole.java:109)
        at org.projog.tools.ProjogConsole.consultScripts(ProjogConsole.java:102)
        at org.projog.tools.ProjogConsole.run(ProjogConsole.java:66)
        at org.projog.tools.ProjogConsole.main(ProjogConsole.java:222)
Expected an atom or a predicate but got a NAMED_VARIABLE with value: X

add writef/2 built-in predicate

writef/2 is similar to Java's System.out.format.

The first argument is a string text containing format specifiers, the format specifiers are replaced with arguments provided and the result output to the output stream.

Example:

?- writef("example: %t %t %t", [a,1,p(z)]).
example: a 1 p(z)

add \=/2 built-in predicate

X = Y is true when X and Y are not unifiable, else false. (i.e. Only evaluates to true if terms are not Prolog unifiable.)

Example use:

?- a \= b.
true.

?- a \= a.
false.

?- a \= X.
false.

add between/3 built-in predicate

First argument is minimum value in range, second argument is maximum value in range.

True if third argument is greater than or equal to integer represented by first argument and less than or equal to the integer represented by the second argument.

Example:

?- between(1, 5, 0).
false.

?- between(1, 5, 1).
true.

?- between(1, 5, 3).
true.

?- between(1, 5, 5).
true.

?- between(1, 5, 6).
false.

?- between(1, 5, X).
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
X = 5.

add float/1 built-in predicate

float(X) is true when X is bound to a floating point number, else false.

Examples:

?- float(0.0).
true.

?- float(1.0).
true.

?- float(-1.0).
true.

?- float(76832.46).
true.

?- float(1).
false.

?- float("1.5").
false.

?- float(1.25+1.75).
false.

Exception using structures as arguments to // (i.e. integer division) function.

Current (incorrect) behaviour:

?- X is 7 * 4 // 2.

org.projog.core.ProjogException: Expected integer but got: STRUCTURE with value: *(7, 4)

Correct behaviour:

?- X is 7 * 4 // 2.

X = 14

yes (16 ms)

Full stack trace:

org.projog.core.ProjogException: Expected integer but got: STRUCTURE with value: *(7, 4)
        at org.projog.core.term.TermUtils.toInt(TermUtils.java:131)
        at org.projog.core.function.math.IntegerDivide.calculate(IntegerDivide.java:19)
        at org.projog.core.function.math.IntegerDivide.calculate(IntegerDivide.java:16)
        at org.projog.core.CalculatableFactory.getNumeric(CalculatableFactory.java:53)
        at org.projog.core.KnowledgeBase.getNumeric(KnowledgeBase.java:115)
        at org.projog.core.function.math.Is.evaluate(Is.java:63)
        at org.projog.core.function.math.Is.evaluate(Is.java:54)
        at org.projog.api.QueryResult.doFirstEvaluationOfQuery(QueryResult.java:66)
        at org.projog.api.QueryResult.next(QueryResult.java:53)
        at org.projog.tools.ProjogConsole.evaluateOnce(ProjogConsole.java:168)
        at org.projog.tools.ProjogConsole.parseAndExecute(ProjogConsole.java:106)
        at org.projog.tools.ProjogConsole.run(ProjogConsole.java:60)
        at org.projog.tools.ProjogConsole.main(ProjogConsole.java:207)

add once/1 built-in predicate

Calls the goal represented by a term - no attempt is made to retry the goal during backtracking.

Example use:

?- once(true).
true.

?- once(fail).
false.

?- once(repeat).
true.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.