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.*;
43  import jTrolog.terms.Double;
44  import jTrolog.terms.Number;
45  import jTrolog.parser.Parser;
46  
47  import java.io.*;
48  import java.util.HashMap;
49  import java.util.Random;
50  
51  /**
52   * This class provides basic I/O predicates.
53   * 
54   * @author ivar.orstavik@hist.no
55   */
56  @SuppressWarnings({ "rawtypes", "unchecked", "serial" })
57  public class IOLibrary extends Library {
58  
59  	private HashMap streams;
60  
61  	private String in;
62  	private String out;
63  
64  	private Random gen = new Random();
65  
66  	public IOLibrary() {
67  		streams = new HashMap();
68  		in = "stdin";
69  		out = "stdout";
70  	}
71  
72  	public boolean see_1(BindingsTable bt, Term arg0) throws Exception {
73  		if (!BasicLibrary.atom_1(bt, arg0))
74  			return false;
75  
76  		String requested = ((Struct) arg0).name;
77  		// 1. close already open stream if seeing a new input, then rename
78  		// current in
79  		if (!requested.equals(in)) {
80  			InputStream inputStream = getInputStream(in);
81  			if (inputStream != null)
82  				inputStream.close();
83  			in = requested;
84  		}
85  
86  		// 2. if the requested stream is not already open, then open it
87  		InputStream newIn = getInputStream(in);
88  		if (newIn == null) {
89  			newIn = new FileInputStream(in);
90  			streams.put(in, newIn);
91  		}
92  		return true;
93  	}
94  
95  	public boolean seen_0(BindingsTable bt) throws Exception {
96  		InputStream inputStream = getInputStream(in);
97  		if (inputStream != null)
98  			inputStream.close();
99  		in = "stdin";
100 		return true;
101 	}
102 
103 	public boolean seeing_1(BindingsTable bt, Term t) {
104 		return bt.unify(t, new StructAtom(in));
105 	}
106 
107 	public boolean tell_1(BindingsTable bt, Term arg0) throws Exception {
108 		if (!BasicLibrary.atom_1(bt, arg0))
109 			return false;
110 
111 		String requested = ((Struct) arg0).name;
112 		// 1. close already open stream if seeing a new input, then rename
113 		// current in
114 		if (!requested.equals(out)) {
115 			OutputStream inputStream = getOutputStream(out);
116 			if (inputStream != null)
117 				inputStream.close();
118 			out = requested;
119 		}
120 
121 		// 2. if the requested stream is not already open, then open it
122 		OutputStream newOut = getOutputStream(out);
123 		if (newOut == null) {
124 			newOut = new FileOutputStream(out);
125 			streams.put(out, newOut);
126 		}
127 		return true;
128 	}
129 
130 	public boolean told_0(BindingsTable bt) throws Exception {
131 		OutputStream outputStream = getOutputStream(out);
132 		if (outputStream != null)
133 			outputStream.close();
134 		out = "stdout";
135 		return true;
136 	}
137 
138 	public boolean telling_1(BindingsTable bt, Term arg0) {
139 		return bt.unify(arg0, new StructAtom(out));
140 	}
141 
142 	public boolean put_1(BindingsTable bt, Term arg0) throws Exception {
143 		if (!BasicLibrary.atom_1(bt, arg0))
144 			return false;
145 
146 		String ch = ((Struct) arg0).name;
147 		if (ch.length() > 1)
148 			return false;
149 		getOutputStream(out).write((byte) ch.charAt(0));
150 		return true;
151 	}
152 
153 	public boolean get0_1(BindingsTable bt, Term arg0) throws Exception {
154 		int ch = getInputStream(in).read();
155 		Term a1 = ch == -1 ? (Term) new Int(-1) : (Term) new StructAtom(Character.toString((char) ch));
156 		return bt.unify(arg0, a1);
157 	}
158 
159 	public boolean get_1(BindingsTable bt, Term arg0) throws Exception {
160 		InputStream inputStream = getInputStream(in);
161 		int ch;
162 		do {
163 			ch = inputStream.read();
164 		} while (ch < 0x20 && ch >= 0);
165 		Term a1 = ch == -1 ? (Term) new Int(-1) : (Term) new StructAtom(Character.toString((char) ch));
166 		return bt.unify(arg0, a1);
167 	}
168 
169 	public boolean tab_1(BindingsTable bt, Int arg) throws Exception {
170 		int n = arg.intValue();
171 		OutputStream outputStream = getOutputStream(out);
172 		for (int i = 0; i < n; i++)
173 			outputStream.write(0x20);
174 		return true;
175 	}
176 
177 	public boolean read_1(BindingsTable bt, Term arg0) throws Exception {
178 		InputStream inputStream = getInputStream(in);
179 		StringBuffer res = new StringBuffer();
180 		boolean single_quotes = false;
181 		boolean double_quotes = false;
182 		do {
183 			int ch = inputStream.read();
184 			if (ch == -1)
185 				break;
186 			else if (ch == '\'')
187 				single_quotes = !single_quotes;
188 			else if (ch == '\"')
189 				double_quotes = !double_quotes;
190 			else if (ch == '.' && !(single_quotes || double_quotes))
191 				break;
192 			res.append((char) ch);
193 		} while (true);
194 		Term result = new Parser(res.toString(), ((Library) this).engine).nextTerm(false);
195 		return bt.unify(arg0, result);
196 	}
197 
198 	public boolean write_1(BindingsTable bt, Term arg0) throws Exception {
199 		OutputStream outputStream = getOutputStream(out);
200 		outputStream.write(arg0.toString().getBytes());
201 		return true;
202 	}
203 
204 	public boolean print_1(BindingsTable bt, Term arg0) throws Exception {
205 		OutputStream outputStream = getOutputStream(out);
206 		outputStream.write(Parser.removeApices(arg0.toString()).getBytes());
207 		return true;
208 	}
209 
210 	public boolean nl_0(BindingsTable bt) throws Exception {
211 		OutputStream outputStream = getOutputStream(out);
212 		outputStream.write('\n');
213 		return true;
214 	}
215 
216 	/**
217 	 * reads a source text from a file. It's useful used with agent predicate:
218 	 * text_from_file(File,Source), agent(Source).
219 	 */
220 	public boolean text_from_file_2(BindingsTable bt, Term file_name, Term text) throws IOException {
221 		StringBuffer res = new StringBuffer();
222 		BufferedReader in;
223 		Object possibleInput = streams.get(Parser.removeApices(file_name.toString()));
224 		if (possibleInput instanceof InputStream) {
225 			in = new BufferedReader(new InputStreamReader((InputStream) possibleInput));
226 		} else {
227 			in = new BufferedReader(new FileReader("infilename"));
228 		}
229 		String str;
230 		while ((str = in.readLine()) != null)
231 			res.append(str);
232 		in.close();
233 
234 		return bt.unify(text, new StructAtom(res.toString()));
235 	}
236 
237 	// miscellanea
238 
239 	public boolean rand_float_1(BindingsTable bt, Term t) {
240 		return bt.unify(t, new Double(gen.nextFloat()));
241 	}
242 
243 	public boolean rand_int_2(BindingsTable bt, Number argNum, Term num) {
244 		return bt.unify(num, new Int(gen.nextInt(argNum.intValue())));
245 	}
246 
247 	public String getTheory() {
248 		return "consult(File) :- text_from_file(File,Text), add_theory(Text).\n"
249 				+ "reconsult(File) :- text_from_file(File,Text), set_theory(Text).\n"
250 				+ "solve_file(File,Goal) :- text_from_file(File,Text),text_term(Text,Goal),call(Goal).\n";
251 	}
252 
253 	public static String readStream(InputStream is) throws IOException {
254 		BufferedReader br = new BufferedReader(new InputStreamReader(is));
255 		StringBuilder sb = new StringBuilder();
256 		String line;
257 		while ((line = br.readLine()) != null)
258 			sb.append(line).append("\n");
259 		br.close();
260 		return sb.toString();
261 	}
262 
263 	private OutputStream getOutputStream(String out) {
264 		if ("stdout".equals(out))
265 			return ((Library) this).engine.getPrintStream();
266 		return (OutputStream) streams.get(out);
267 	}
268 
269 	private InputStream getInputStream(String in) {
270 		if ("stdout".equals(in))
271 			return System.in;
272 		return (InputStream) streams.get(in);
273 	}
274 }