Access Control is now enabled for Gitlab Pages so you can now restrict Pages to authorized users only. If needed, make your website publicly available : Navigate to your project's Settings > General > Visibility and select Everyone in pages section.

Commit 0ac3436a authored by Tony Licata's avatar Tony Licata

Can now use any kind of operators for is/2 (not only 2 args operators), added...

Can now use any kind of operators for is/2 (not only 2 args operators), added sign/1, cos/1, sin/1, etc... and also added constants pi/0 e/0 tau/0
parent 510d22a4
......@@ -2,9 +2,8 @@ package ch.heiafr.prolograal.builtins.predicates;
import ch.heiafr.prolograal.runtime.*;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.*;
import java.util.function.Function;
/**
* Class representing the is/2(A,B) predicate.
......@@ -19,8 +18,7 @@ public final class ProloGraalIsBuiltin extends ProloGraalBuiltinClause {
private ProloGraalVariable arg; // the variable A in is(A,B). We keep it to use it in the execute method
private ProloGraalVariable arg2; // the variable B in is(A,B). We keep it to use it in the execute method
//TODO: do not use a bifunction to permet functions like sin(X).
private final Map<ProloGraalAtom, BiFunction<ProloGraalNumber, ProloGraalNumber, ProloGraalNumber>> operations;
private final Map<ProloGraalAtom, Function<List<ProloGraalNumber>,ProloGraalNumber>> operations;
public ProloGraalIsBuiltin(ProloGraalContext context) {
super();
......@@ -29,14 +27,20 @@ public final class ProloGraalIsBuiltin extends ProloGraalBuiltinClause {
// we fill the operations map to check the operator used by the user later in the execute method
operations = new HashMap<>();
operations.put(new ProloGraalAtom(getVariables(),"'+'"),(a,b)->new ProloGraalDoubleNumber(getVariables(),a.asDouble()+b.asDouble()));
operations.put(new ProloGraalAtom(getVariables(),"'-'"),(a,b)->new ProloGraalDoubleNumber(getVariables(),a.asDouble()-b.asDouble()));
operations.put(new ProloGraalAtom(getVariables(),"'*'"),(a,b)->new ProloGraalDoubleNumber(getVariables(),a.asDouble()*b.asDouble()));
operations.put(new ProloGraalAtom(getVariables(),"'/'"),(a,b)->new ProloGraalDoubleNumber(getVariables(),a.asDouble()/b.asDouble()));
operations.put(new ProloGraalAtom(getVariables(),"'**'"),(a,b)->new ProloGraalDoubleNumber(getVariables(),Math.pow(a.asDouble(),b.asDouble())));
operations.put(new ProloGraalAtom(getVariables(),"'mod'"),(a,b)->{double ad = a.asDouble();double bd = b.asDouble();double res = ((ad % bd + bd) % bd);return new ProloGraalDoubleNumber(getVariables(),res);});
operations.put(new ProloGraalAtom(getVariables(),"'<'"),(a,b)->{double res = a.asDouble()<b.asDouble()?1:0;return new ProloGraalDoubleNumber(getVariables(),res);});
operations.put(new ProloGraalAtom(getVariables(),"'>'"),(a,b)->{double res = a.asDouble()>b.asDouble()?1:0;return new ProloGraalDoubleNumber(getVariables(),res);});
operations.put(new ProloGraalAtom(getVariables(),"'pi'"),this::pi);
operations.put(new ProloGraalAtom(getVariables(),"'e'"),this::e);
operations.put(new ProloGraalAtom(getVariables(),"'tau'"),this::tau);
operations.put(new ProloGraalAtom(getVariables(),"'+'"),this::add);
operations.put(new ProloGraalAtom(getVariables(),"'-'"),this::substract);
operations.put(new ProloGraalAtom(getVariables(),"'*'"),this::multiply);
operations.put(new ProloGraalAtom(getVariables(),"'/'"),this::divide);
operations.put(new ProloGraalAtom(getVariables(),"'**'"),this::pow);
operations.put(new ProloGraalAtom(getVariables(),"'^'"), this::pow);
operations.put(new ProloGraalAtom(getVariables(),"'mod'"),this::mod);
operations.put(new ProloGraalAtom(getVariables(),"'sign'"),this::sign);
operations.put(new ProloGraalAtom(getVariables(),"'sin'"),this::sin);
operations.put(new ProloGraalAtom(getVariables(),"'cos'"),this::cos);
operations.put(new ProloGraalAtom(getVariables(),"'abs'"),this::abs);
// create the head of this clause
// since we do not need custom unification, a simple structure is enough
......@@ -83,27 +87,30 @@ public final class ProloGraalIsBuiltin extends ProloGraalBuiltinClause {
ProloGraalNumber number = null;
if(term.isNumber()){
number = term.asNumber();
}else if(term instanceof ProloGraalStructure && ((ProloGraalStructure) term).getArguments().size()==2){
}else if(term.isStructure()){
number = consultOperation((ProloGraalStructure)term);
}else if(term.isAtom()){
ProloGraalStructure arglessStruct = new ProloGraalStructure(getVariables());
arglessStruct.setFunctor(term.asAtom());
number = consultOperation(arglessStruct);
}
return number;
}
private ProloGraalNumber consultOperation(ProloGraalStructure operation){
ProloGraalTerm leftTerm = operation.getArguments().get(0);
ProloGraalTerm rightTerm = operation.getArguments().get(1);
ProloGraalNumber leftNumber = consultTerm(leftTerm);
ProloGraalNumber rightNumber = consultTerm(rightTerm);
if(leftNumber == null || rightNumber == null) return null;
return computeOperation(operation.getFunctor(), leftNumber, rightNumber);
List<ProloGraalNumber> results = new ArrayList<>();
for( ProloGraalTerm term : operation.getArguments() ){
ProloGraalNumber res = consultTerm(term);
if(res == null) return null;
results.add(res);
}
return computeOperation(operation.getFunctor(), results);
}
private ProloGraalNumber computeOperation(ProloGraalAtom functor,
ProloGraalNumber leftNumber, ProloGraalNumber rightNumber){
List<ProloGraalNumber> args){
if(operations.containsKey(functor)){
return operations.get(functor).apply(leftNumber,rightNumber);
return operations.get(functor).apply(args);
}
return null;
}
......@@ -114,4 +121,76 @@ public final class ProloGraalIsBuiltin extends ProloGraalBuiltinClause {
return new ProloGraalIsBuiltin(context);
}
private ProloGraalNumber pi(List<ProloGraalNumber> args){
if(!args.isEmpty())return null;
return new ProloGraalDoubleNumber(getVariables(),Math.PI);
}
private ProloGraalNumber e(List<ProloGraalNumber> args){
if(!args.isEmpty())return null;
return new ProloGraalDoubleNumber(getVariables(),Math.E);
}
private ProloGraalNumber tau(List<ProloGraalNumber> args){
if(!args.isEmpty())return null;
return new ProloGraalDoubleNumber(getVariables(),Math.PI*2);
}
private ProloGraalNumber add(List<ProloGraalNumber> args){
if(args.size()!=2)return null;
return new ProloGraalDoubleNumber(getVariables(),args.get(0).asDouble()+args.get(1).asDouble());
}
private ProloGraalNumber substract(List<ProloGraalNumber> args){
if(args.size()!=2)return null;
return new ProloGraalDoubleNumber(getVariables(),args.get(0).asDouble()-args.get(1).asDouble());
}
private ProloGraalNumber multiply(List<ProloGraalNumber> args){
if(args.size()!=2)return null;
return new ProloGraalDoubleNumber(getVariables(),args.get(0).asDouble()*args.get(1).asDouble());
}
private ProloGraalNumber divide(List<ProloGraalNumber> args){
if(args.size()!=2)return null;
return new ProloGraalDoubleNumber(getVariables(),args.get(0).asDouble()/args.get(1).asDouble());
}
private ProloGraalNumber pow(List<ProloGraalNumber> args){
if(args.size()!=2)return null;
return new ProloGraalDoubleNumber(getVariables(),Math.pow(args.get(0).asDouble(),args.get(1).asDouble()));
}
private ProloGraalNumber mod(List<ProloGraalNumber> args){
if(args.size()!=2)return null;
double ad = args.get(0).asDouble();
double bd = args.get(1).asDouble();
double res = ((ad % bd + bd) % bd);
return new ProloGraalDoubleNumber(getVariables(),res);
}
private ProloGraalNumber sign(List<ProloGraalNumber> args){
if(args.size()!=1)return null;
double val = args.get(0).asDouble();
int res = 0;
if(val>0) res = 1;
if(val<0) res = -1;
return new ProloGraalDoubleNumber(getVariables(),res);
}
private ProloGraalNumber sin(List<ProloGraalNumber> args){
if(args.size()!=1)return null;
return new ProloGraalDoubleNumber(getVariables(),Math.sin(args.get(0).asDouble()));
}
private ProloGraalNumber cos(List<ProloGraalNumber> args){
if(args.size()!=1)return null;
return new ProloGraalDoubleNumber(getVariables(),Math.cos(args.get(0).asDouble()));
}
private ProloGraalNumber abs(List<ProloGraalNumber> args){
if(args.size()!=1)return null;
return new ProloGraalDoubleNumber(getVariables(),Math.abs(args.get(0).asDouble()));
}
}
......@@ -2,5 +2,4 @@ consultstring(~test(10). test(12). string(abc).~).
test(A), string(abc), test(12).
is(A,'**'(2,10)).
is(2,'+'(1,1)).
is(1,'>'(10,'+'(2,2))).
test(B), is(C,'*'(B,B)).
......@@ -8,8 +8,6 @@ A = 1024.0
yes
% is(2,'+'(1,1)).
yes
% is(1,'>'(10,'+'(2,2))).
yes
% test(B), is(C,'*'(B,B)).
B = 10
C = 100.0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment