/*
* tuProlog - Copyright (C) 2001-2002 aliCE team at deis.unibo.it
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package alice.tuprolog.lib;
import alice.tuprolog.Functor;
import alice.tuprolog.Int;
import alice.tuprolog.Library;
import alice.tuprolog.Number;
import alice.tuprolog.Predicate;
import alice.tuprolog.Struct;
import alice.tuprolog.Term;
import alice.tuprolog.Var;
/**
* This class represents a tuProlog library providing most of the built-ins
* predicates and functors defined by ISO standard.
*
* Library/Theory dependency: BasicLibrary
*/
public class ISOLibrary extends Library {
public ISOLibrary() {
}
@Predicate("atom_length/2")
public boolean atomLength(Term arg, Term len) {
arg = arg.getTerm();
if (!(arg instanceof Struct))
return false;
Struct arg0 = (Struct) arg;
if (!arg0.isAtom())
return false;
return unify(len,new Int(arg0.getName().length()));
}
@Predicate("atom_chars/2")
public boolean atomChars(Term arg0, Term arg1) {
arg0 = arg0.getTerm();
arg1 = arg1.getTerm();
if (arg0 instanceof Var) {
if (!arg1.isList())
return false;
Struct list = (Struct) arg1;
if (list.isEmptyList())
return unify(arg0, new Struct(""));
String st = "";
while (!(list.isEmptyList())) {
String st1 = list.getTerm(0).toString();
try {
if (st1.startsWith("'") && st1.endsWith("'"))
st1 = st1.substring(1, st1.length() - 1);
} catch (Exception ex) {};
st = st.concat(st1);
list = (Struct) list.getTerm(1);
}
return unify(arg0, new Struct(st));
} else {
if (!arg0.isAtom())
return false;
String st = ((Struct)arg0).getName();
Term[] tlist = new Term[st.length()];
for (int i = 0; i < st.length(); i++)
tlist[i] = new Struct(new String(new char[] { st.charAt(i) }));
Struct list = new Struct(tlist);
return unify(arg1,list);
}
}
@Predicate("char_code/2")
public boolean charCode(Term arg0, Term arg1) {
arg0 = arg0.getTerm();
arg1 = arg1.getTerm();
if (arg1 instanceof Var) {
if (arg0.isAtom()) {
String st = ((Struct) arg0).getName();
if (st.length() <= 1)
return unify(arg1, new Int(st.charAt(0)));
}
} else if ((arg1 instanceof Int) || (arg1 instanceof alice.tuprolog.Long)) {
char c = (char) ((Number) arg1).intValue();
return unify(arg0, new Struct("" + c));
}
return false;
}
// functors
@Functor("sin/1")
public Term sin(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new alice.tuprolog.Double(Math.sin(((Number)val0).doubleValue()));
return null;
}
@Functor("cos/1")
public Term cos(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new alice.tuprolog.Double(Math.cos(((Number)val0).doubleValue()));
return null;
}
@Functor("exp/1")
public Term exp(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new alice.tuprolog.Double(Math.exp(((Number)val0).doubleValue()));
return null;
}
@Functor("atan/1")
public Term atan(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new alice.tuprolog.Double(Math.atan(((Number)val0).doubleValue()));
return null;
}
@Functor("log/1")
public Term log(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new alice.tuprolog.Double(Math.log(((Number)val0).doubleValue()));
return null;
}
@Functor("sqrt/1")
public Term sqrt(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new alice.tuprolog.Double(Math.sqrt(((Number)val0).doubleValue()));
return null;
}
@Functor("abs/1")
public Term abs(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Int || val0 instanceof alice.tuprolog.Long)
return new alice.tuprolog.Int(Math.abs(((Number)val0).intValue()));
if (val0 instanceof alice.tuprolog.Double || val0 instanceof alice.tuprolog.Float)
return new alice.tuprolog.Double(Math.abs(((Number)val0).doubleValue()));
return null;
}
@Functor("sign/1")
public Term sign(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Int || val0 instanceof alice.tuprolog.Long)
return new alice.tuprolog.Double(((Number)val0).intValue()>0 ? 1.0: -1.0);
if (val0 instanceof alice.tuprolog.Double || val0 instanceof alice.tuprolog.Float)
return new alice.tuprolog.Double(((Number)val0).doubleValue()>0 ? 1.0: -1.0);
return null;
}
@Functor("float_integer_part/1")
public Term floatIntegerPart(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new alice.tuprolog.Double((long)Math.rint(((Number)val0).doubleValue()));
return null;
}
@Functor("float_fractional_part/1")
public Term floatFractionalPart(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number) {
double fl = ((Number)val0).doubleValue();
return new alice.tuprolog.Double(Math.abs(fl-Math.rint(fl)));
}
return null;
}
@Functor("float/1")
public Term toFloat(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new alice.tuprolog.Double(((Number) val0).doubleValue());
return null;
}
@Functor("floor/1")
public Term floor(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new Int((int) Math.floor(((Number) val0).doubleValue()));
return null;
}
@Functor("round/1")
public Term round(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new alice.tuprolog.Long(Math.round(((Number) val0).doubleValue()));
return null;
}
@Functor("truncate/1")
public Term truncate(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new Int((int) Math.rint(((Number) val0).doubleValue()));
return null;
}
@Functor("ceiling/1")
public Term ceiling(Term val) {
Term val0 = evalExpression(val);
if (val0 instanceof Number)
return new Int((int) Math.ceil(((Number) val0).doubleValue()));
return null;
}
@Functor("div/2")
public Term div(Term v0, Term v1) {
Term val0 = evalExpression(v0);
Term val1 = evalExpression(v1);
if (val0 instanceof Number && val1 instanceof Number)
return new alice.tuprolog.Int(((Number) val0).intValue() / ((Number) val1).intValue());
return null;
}
@Functor("mod/2")
public Term mod(Term v0, Term v1) {
Term val0 = evalExpression(v0);
Term val1 = evalExpression(v1);
if (val0 instanceof Number && val1 instanceof Number) {
int x = ((Number) val0).intValue();
int y = ((Number) val1).intValue();
int f = new java.lang.Double(Math.floor((double) x / (double) y)).intValue();
return new Int(x - (f * y));
}
return null;
}
@Functor("rem/2")
public Term rem(Term v0, Term v1) {
Term val0 = evalExpression(v0);
Term val1 = evalExpression(v1);
if (val0 instanceof Number && val1 instanceof Number)
return new alice.tuprolog.Double(Math.IEEEremainder(((Number) val0).doubleValue(), ((Number) val1).doubleValue()));
return null;
}
@Override
public String getTheory(){
return
//
// operators defined by the ISOLibrary theory
//
":- op( 300, yfx, 'div'). \n"+
":- op( 400, yfx, 'mod'). \n"+
":- op( 400, yfx, 'rem'). \n"+
":- op( 200, fx, 'sin'). \n"+
":- op( 200, fx, 'cos'). \n"+
":- op( 200, fx, 'sqrt'). \n"+
":- op( 200, fx, 'atan'). \n"+
":- op( 200, fx, 'exp'). \n"+
":- op( 200, fx, 'log'). \n"+
//
// flags defined by the ISOLibrary theory
//
":- flag(bounded, [true,false], true, false).\n"+
":- flag(max_integer, [" + new Integer(Integer.MAX_VALUE).toString() + "], " + new Integer(Integer.MAX_VALUE).toString() + ",false).\n"+
":- flag(min_integer, [" + new Integer(Integer.MIN_VALUE).toString() + "], " + new Integer(Integer.MIN_VALUE).toString() + ",false).\n"+
":- flag(integer_rounding_function, [up,down], down, false).\n"+
":- flag(char_conversion,[on,off],off,false).\n"+
":- flag(debug,[on,off],off,false).\n"+
":- flag(max_arity, [" + new Integer(Integer.MAX_VALUE).toString() + "], " + new Integer(Integer.MAX_VALUE).toString() + ",false).\n"+
":- flag(undefined_predicate, [error,fail,warning], fail, false).\n"+
":- flag(double_quotes, [atom,chars,codes], atom, false).\n"+
//
"atom_concat(F,S,R) :- atom_chars(F,FL),atom_chars(S,SL),!,append(FL,SL,RS),atom_chars(R,RS).\n " +
"atom_concat(F,S,R) :- atom_chars(R,RS),append(FL,SL,RS),atom_chars(F,FL),atom_chars(S,SL).\n " +
"atom_codes(A,L):-atom_chars(A,L1),!,chars_codes(L1,L).\n"+
"atom_codes(A,L):-chars_codes(L1,L),atom_chars(A,L1).\n"+
"chars_codes([],[]).\n"+
"chars_codes([X|L1],[Y|L2]):-char_code(X,Y),chars_codes(L1,L2).\n"+
"sub_atom(Atom,B,L,A,Sub):-atom_chars(Atom,L1),atom_chars(Sub,L2),!,sub_list(L2,L1,B),length(L2,L), length(L1,Len), A is Len-(B+L).\n"+
"sub_atom(Atom,B,L,A,Sub):-atom_chars(Atom,L1),sub_list(L2,L1,B),atom_chars(Sub,L2),length(L2,L), length(L1,Len), A is Len-(B+L).\n"+
"sub_list([],_,0).\n"+
"sub_list([X|L1],[X|L2],0):- sub_list_seq(L1,L2).\n"+
"sub_list(L1,[_|L2],N):- sub_list(L1,L2,M), N is M + 1.\n"+
"sub_list_seq([],L).\n"+
"sub_list_seq([X|L1],[X|L2]):-sub_list_seq(L1,L2).\n"+
"number_chars(Number,List):-num_atom(Number,Struct),atom_chars(Struct,List),!.\n"+
"number_chars(Number,List):-atom_chars(Struct,List),num_atom(Number,Struct).\n"+
"number_codes(Number,List):-num_atom(Number,Struct),atom_codes(Struct,List),!.\n"+
"number_codes(Number,List):-atom_codes(Struct,List),num_atom(Number,Struct).\n";
//
// ISO default
//"current_prolog_flag(changeable_flags,[ char_conversion(on,off), debug(on,off), undefined_predicate(error,fail,warning),double_quotes(chars,codes,atom) ]).\n" +
//"current_prolog_flag(changeable_flags,[]).\n" +
}
}