View Javadoc

1   /*
2    * #%L
3    * prolobjectlink-jpi-jtrolog
4    * %%
5    * Copyright (C) 2012 - 2018 WorkLogic Project
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as
9    * published by the Free Software Foundation, either version 2.1 of the
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-2.1.html>.
20   * #L%
21   */
22  /*
23   * tuProlog - Copyright (C) 2001-2002  aliCE team at deis.unibo.it
24   *
25   * This library is free software; you can redistribute it and/or
26   * modify it under the terms of the GNU Lesser General Public
27   * License as published by the Free Software Foundation; either
28   * version 2.1 of the License, or (at your option) any later version.
29   *
30   * This library is distributed in the hope that it will be useful,
31   * but WITHOUT ANY WARRANTY; without even the implied warranty of
32   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
33   * Lesser General Public License for more details.
34   *
35   * You should have received a copy of the GNU Lesser General Public
36   * License along with this library; if not, write to the Free Software
37   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
38   */
39  package jTrolog.lib;
40  
41  import jTrolog.engine.*;
42  import jTrolog.terms.Number;
43  import jTrolog.terms.*;
44  import jTrolog.terms.Float;
45  import jTrolog.parser.Parser;
46  import jTrolog.errors.PrologException;
47  
48  import java.util.Iterator;
49  
50  /**
51   * This class represents a tuProlog library providing most of the built-ins
52   * predicates and functors defined by ISO standard.
53   * 
54   * Library/Theory dependency: BasicLibrary
55   * 
56   * 
57   * 
58   */
59  @SuppressWarnings({ "rawtypes", "serial" })
60  public class ISOLibrary extends Library {
61  
62  	public boolean atom_length_2(BindingsTable bt, Struct arg, Term len) {
63  		if (!BasicLibrary.atom_1(bt, arg))
64  			return false;
65  		return bt.unify(len, new Int(arg.name.length()));
66  	}
67  
68  	public boolean atom_chars_2(BindingsTable bt, Term arg0, Term arg1) throws PrologException {
69  		if (arg0 instanceof Var) {
70  			if (!(arg1 instanceof Struct))
71  				return false;
72  
73  			Struct list = (Struct) arg1;
74  			if (list.equals(Term.emptyList))
75  				return bt.unify(arg0, new StructAtom(""));
76  			StringBuffer res = new StringBuffer();
77  			for (Iterator it = bt.structListIterator(list, true); it.hasNext();) {
78  				String character = it.next().toString();
79  				if (character.startsWith("'") && character.endsWith("'") && character.length() != 1)
80  					character = character.substring(1, character.length() - 1);
81  				res.append(character);
82  			}
83  			return bt.unify(arg0, new StructAtom(res.toString()));
84  		} else {
85  			if (!BasicLibrary.atom_1(bt, arg0))
86  				return false;
87  			Struct list = Parser.stringToStructList(((Struct) arg0).name);
88  			return bt.unify(arg1, bt.wrapWithID(list));
89  		}
90  	}
91  
92  	public boolean char_code_2(BindingsTable bt, Term arg0, Term arg1) {
93  		if (arg1 instanceof Var) {
94  			if (BasicLibrary.atom_1(bt, arg0)) {
95  				String st = ((Struct) arg0).name;
96  				if (st.length() <= 1)
97  					return bt.unify(arg1, new Int(st.charAt(0)));
98  			}
99  		} else if (arg1 instanceof Int) {
100 			char c = (char) ((jTrolog.terms.Number) arg1).intValue();
101 			return bt.unify(arg0, new StructAtom("" + c));
102 		}
103 		return false;
104 	}
105 
106 	//
107 
108 	// functors
109 
110 	public Term sin_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
111 		return new jTrolog.terms.Double(Math.sin(bt.evalExpression(engine, val).doubleValue()));
112 	}
113 
114 	public Term cos_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
115 		return new jTrolog.terms.Double(Math.cos(bt.evalExpression(engine, val).doubleValue()));
116 	}
117 
118 	public Term exp_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
119 		return new jTrolog.terms.Double(Math.exp((bt.evalExpression(engine, val)).doubleValue()));
120 	}
121 
122 	public Term atan_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
123 		return new jTrolog.terms.Double(Math.atan(bt.evalExpression(engine, val).doubleValue()));
124 	}
125 
126 	public Term log_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
127 		return new jTrolog.terms.Double(Math.log(bt.evalExpression(engine, val).doubleValue()));
128 	}
129 
130 	public Term sqrt_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
131 		return new jTrolog.terms.Double(Math.sqrt(bt.evalExpression(engine, val).doubleValue()));
132 	}
133 
134 	public Term abs_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
135 		Number val0 = bt.evalExpression(engine, val);
136 		if (val0 instanceof Float)
137 			return new jTrolog.terms.Double(Math.abs(val0.doubleValue()));
138 		return new jTrolog.terms.Int(Math.abs(val0.intValue()));
139 	}
140 
141 	public Term sign_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
142 		Number val0 = bt.evalExpression(engine, val);
143 		if (val0 instanceof Float)
144 			return new jTrolog.terms.Double(val0.doubleValue() > 0 ? 1.0 : -1.0);
145 		return new jTrolog.terms.Double(val0.intValue() > 0 ? 1.0 : -1.0);
146 	}
147 
148 	public Term float_integer_part_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
149 		return new jTrolog.terms.Double((long) Math.rint(bt.evalExpression(engine, val).doubleValue()));
150 	}
151 
152 	public Term float_fractional_part_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
153 		double fl = bt.evalExpression(engine, val).doubleValue();
154 		return new jTrolog.terms.Double(Math.abs(fl - Math.rint(fl)));
155 	}
156 
157 	// public boolean float_1(BindingsTable bt, EvaluableTerm val) throws
158 	// Throwable {
159 	// return engine.evalExpression(bt, val).isReal();
160 	// }
161 
162 	public Term floor_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
163 		return new Int((int) Math.floor(bt.evalExpression(engine, val).doubleValue()));
164 	}
165 
166 	public Term round_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
167 		return new jTrolog.terms.Long(Math.round(bt.evalExpression(engine, val).doubleValue()));
168 	}
169 
170 	public Term truncate_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
171 		return new Int((int) Math.rint(bt.evalExpression(engine, val).doubleValue()));
172 	}
173 
174 	public Term ceiling_1(BindingsTable bt, EvaluableTerm val) throws Throwable {
175 		return new Int((int) Math.ceil(bt.evalExpression(engine, val).doubleValue()));
176 	}
177 
178 	public Term div_2(BindingsTable bt, EvaluableTerm v0, EvaluableTerm v1) throws Throwable {
179 		return new jTrolog.terms.Int(bt.evalExpression(engine, v0).intValue() / bt.evalExpression(engine, v1).intValue());
180 	}
181 
182 	public Term mod_2(BindingsTable bt, EvaluableTerm v0, EvaluableTerm v1) throws Throwable {
183 		return new Int(bt.evalExpression(engine, v0).intValue() % bt.evalExpression(engine, v1).intValue());
184 	}
185 
186 	public Term rem_2(BindingsTable bt, EvaluableTerm v0, EvaluableTerm v1) throws Throwable {
187 		return new jTrolog.terms.Double(Math.IEEEremainder(bt.evalExpression(engine, v0).doubleValue(), bt.evalExpression(engine, v1).doubleValue()));
188 	}
189 
190 	/**
191 	 * library theory
192 	 */
193 	public String getTheory() {
194 		return
195 		//
196 		// operators defined by the ISOLibrary theory
197 		//
198 		":- 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"
199 				+ ":- op(  200, fx,   'sqrt'). \n" + ":- op(  200, fx,   'atan'). \n" + ":- op(  200, fx,   'exp'). \n" + ":- op(  200, fx,   'log'). \n" +
200 				//
201 				// flags defined by the ISOLibrary theory
202 				//
203 				":- flag(bounded, [true,false], true, false).\n" + ":- flag(max_integer, ["
204 				+ Integer.toString(Integer.MAX_VALUE)
205 				+ "], "
206 				+ Integer.toString(Integer.MAX_VALUE)
207 				+ ",false).\n"
208 				+ ":- flag(min_integer, ["
209 				+ Integer.toString(Integer.MIN_VALUE)
210 				+ "], "
211 				+ Integer.toString(Integer.MIN_VALUE)
212 				+ ",false).\n"
213 				+ ":- flag(integer_rounding_function, [up,down], down, false).\n"
214 				+ ":- flag(char_conversion,[on,off],off,false).\n"
215 				+ ":- flag(debug,[on,off],off,false).\n"
216 				+ ":- flag(max_arity, ["
217 				+ Integer.toString(Integer.MAX_VALUE)
218 				+ "], "
219 				+ Integer.toString(Integer.MAX_VALUE)
220 				+ ",false).\n"
221 				+ ":- flag(undefined_predicate, [error,fail,warning], fail, false).\n"
222 				+ ":- flag(double_quotes, [atom,chars,codes], atom, true).\n"
223 				+
224 				//
225 				//
226 				"unbound(X):-not bound(X).\n                                                                          "
227 				+
228 				//
229 				"atom_concat(F,S,R) :- atom_chars(F,FL),atom_chars(S,SL),!,append(FL,SL,RS),atom_chars(R,RS).\n          "
230 				+ "atom_concat(F,S,R) :- atom_chars(R,RS),append(FL,SL,RS),atom_chars(F,FL),atom_chars(S,SL).\n            "
231 				+ "atom_codes(A,L):-atom_chars(A,L1),!,chars_codes(L1,L).\n"
232 				+ "atom_codes(A,L):-chars_codes(L1,L),atom_chars(A,L1).\n"
233 				+ "chars_codes([],[]).\n"
234 				+ "chars_codes([X|L1],[Y|L2]):-char_code(X,Y),chars_codes(L1,L2).\n"
235 				+ "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"
236 				+ "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"
237 				+ "sub_list([],_,0).\n"
238 				+ "sub_list([X|L1],[X|L2],0):- sub_list_seq(L1,L2).\n"
239 				+ "sub_list(L1,[_|L2],N):- sub_list(L1,L2,M), N is M + 1.\n"
240 				+ "sub_list_seq([],L).\n"
241 				+ "sub_list_seq([X|L1],[X|L2]):-sub_list_seq(L1,L2).\n"
242 				+ "number_chars(Number,List):-num_atom(Number,Struct),atom_chars(Struct,List),!.\n"
243 				+ "number_chars(Number,List):-atom_chars(Struct,List),num_atom(Number,Struct).\n"
244 				+ "number_codes(Number,List):-num_atom(Number,Struct),atom_codes(Struct,List),!.\n"
245 				+ "number_codes(Number,List):-atom_codes(Struct,List),num_atom(Number,Struct).\n";
246 		//
247 		// ISO default
248 		// "current_prolog_flag(changeable_flags,[ char_conversion(on,off), debug(on,off), undefined_predicate(error,fail,warning),double_quotes(chars,codes,atom) ]).\n"+
249 		// "current_prolog_flag(changeable_flags,[]).\n                                                              "+
250 	}
251 
252 	public String[] getSynonym(String primitiveName) {
253 		if (primitiveName.equals("ground"))
254 			return new String[] { "bound" };
255 		return null;
256 	}
257 
258 }