001    package net.sf.cpsolver.ifs.util;
002    
003    import java.io.*;
004    import java.util.*;
005    
006    /** A class for reading prolog files.
007     *
008     * @version
009     * IFS 1.1 (Iterative Forward Search)<br>
010     * Copyright (C) 2006 Tomáš Müller<br>
011     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
012     * Lazenska 391, 76314 Zlin, Czech Republic<br>
013     * <br>
014     * This library is free software; you can redistribute it and/or
015     * modify it under the terms of the GNU Lesser General Public
016     * License as published by the Free Software Foundation; either
017     * version 2.1 of the License, or (at your option) any later version.
018     * <br><br>
019     * This library is distributed in the hope that it will be useful,
020     * but WITHOUT ANY WARRANTY; without even the implied warranty of
021     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
022     * Lesser General Public License for more details.
023     * <br><br>
024     * You should have received a copy of the GNU Lesser General Public
025     * License along with this library; if not, write to the Free Software
026     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
027     */
028    public class PrologFile implements Iterator {
029        private java.io.BufferedReader iBufferedReader = null;
030        private Term iNextTerm = null;
031        
032        public PrologFile(String file) throws java.io.IOException {
033            iBufferedReader = new BufferedReader(new FileReader(file));
034            iNextTerm = (iBufferedReader.ready()?readTerm(new SpecialReader(iBufferedReader)):null);
035            if (iNextTerm==null) iBufferedReader.close(); else iBufferedReader.readLine();
036        }
037        
038        /** Reads a prolog file. It returns a set of terms */
039        public static Vector readTermsFromStream(java.io.InputStream is, String term) throws java.io.IOException {
040            BufferedReader br = new BufferedReader(new InputStreamReader(is));
041            Vector ret = new Vector();
042            //int x=0;
043            while (br.ready()) {
044                Term t = readTerm(new SpecialReader(br));
045                //System.out.println(t);
046                //x++;
047                //if (x>10) break;
048                if (t!=null && t.getText()!=null && t.getText().startsWith(term)) {
049                    ret.addElement(t);
050                }
051                br.readLine();
052            }
053            br.close();
054            return ret;
055        }
056        
057        /** Writes a set of terms. */
058        public static void writeTerms(PrintWriter pw, Vector terms) throws java.io.IOException {
059            for (Enumeration e=terms.elements();e.hasMoreElements();) {
060                Term t = (Term)e.nextElement();
061                writeTerm(pw,t);
062            }
063        }
064        
065        /** reads a term */
066        private static Term readTerm( SpecialReader is) throws IOException {
067            StringBuffer text=new StringBuffer();
068            Vector content = null;
069            int i;
070            if ((i = is.read())>=0) {
071                while ((char)i=='%' || (char)i==':') {
072                    do {
073                        i=is.read();
074                    } while (i>=0 && !( i==0x0d || i==0x0a ));
075                    i=is.read();
076                    if (i>=0 && (i==0x0d || i==0x0a )) i=is.read();
077                }
078                if (i>=0) is.flush((char)i);
079            }
080            char prev = (char)i;
081            if (i>=0) while ((i = is.read())>=0) {
082                char ch = (char)i;
083                if (ch=='\n' || ch=='\r')
084                    if (prev=='.') break; else continue;
085                if (ch=='(' || ch=='[') {
086                    content = new Vector();
087                    content.addElement(readTerm(is));
088                } else if (content==null && (ch==',' || ch==')' || ch==']')) {
089                    is.flush(ch);
090                    break;
091                } else if (ch==',') content.addElement(readTerm(is));
092                else if (ch==')' || ch==']') break;
093                else text.append(ch);
094                prev = ch;
095            } else return null;
096            Term ret =  new Term(text.toString().trim(),content);
097            return ret;
098        }
099        
100        /** writes a term */
101        private static void writeTerm( PrintWriter pw, Term t) {
102            pw.println(t.toString()+".");
103        }
104        
105        
106        public boolean hasNext() {
107            return iNextTerm!=null;
108        }
109        
110        public Object next() {
111            Term ret = iNextTerm;
112            try {
113                iNextTerm = (iBufferedReader.ready()?readTerm(new SpecialReader(iBufferedReader)):null);
114            } catch (java.io.IOException x) {
115                iNextTerm = null;
116            }
117            try {
118                if (iNextTerm==null) iBufferedReader.close(); else iBufferedReader.readLine();
119            } catch (java.io.IOException x) {}
120            return ret;
121        }
122        
123        public void remove() {
124        }
125        
126        /** Flushable reader -- extension of java.io.Reader */
127        private static class SpecialReader {
128            /** reader */
129            private Reader iReader = null;
130            /** flushed characters */
131            private StringBuffer iFlushedChars = new StringBuffer();
132            
133            /** constructor */
134            public SpecialReader(Reader r) {
135                iReader = r;
136            }
137            
138            /** reads a byte */
139            public int read() throws java.io.IOException {
140                if (iFlushedChars.length()==0) return iReader.read();
141                char ret=iFlushedChars.charAt(0);
142                iFlushedChars.deleteCharAt(0);
143                return ret;
144            }
145            
146            /** flush (return to stream) a character */
147            public void flush(char ch) {
148                iFlushedChars.insert(0,ch);
149            }
150        }
151        
152        /** Term -- it can contain a text and a content (set of terms) */
153        public static class Term {
154            /** text */
155            private String iText = null;
156            /** content */
157            private Vector iContent = null;
158            
159            public boolean equals(Object o) {
160                if (o==null || !(o instanceof Term)) return false;
161                Term t = (Term)o;
162                if (iText==null && t.iText!=null) return false;
163                if (iText!=null && t.iText==null) return false;
164                if (iText!=null && !iText.equals(t.iText)) return false;
165                if (iContent==null && t.iContent!=null) return false;
166                if (iContent!=null && t.iContent==null) return false;
167                if (iContent!=null && !iContent.equals(t.iContent)) return false;
168                return true;
169            }
170            
171            /** constructor */
172            public Term(String text) {
173                iText = text;
174                iContent = null;
175            }
176            
177            /** constructor */
178            public Term(Vector content) {
179                iText = null;
180                iContent = content;
181            }
182            
183            /** constructor */
184            public Term(String text, Vector content) {
185                iText = text;
186                iContent = content;
187            }
188            
189            /** constructor */
190            public Term(String text, Term[] content) {
191                iText = text;
192                if (content==null) {
193                    iContent = null;
194                } else {
195                    iContent = new Vector();
196                    for (int i=0;i<content.length;i++)
197                        iContent.addElement(content[i]);
198                }
199            }
200            
201            /** constructor */
202            public Term(Term[] content) {
203                this(null,content);
204            }
205            
206            /** return text */
207            public String getText() {
208                return iText;
209            }
210            
211            /** return content */
212            public Vector getContent() {
213                return iContent;
214            }
215            
216            /** content size */
217            public int size() {
218                return (iContent==null?-1:iContent.size());
219            }
220            
221            /** return text as int */
222            public int toInt() {
223                return Integer.parseInt(iText);
224            }
225            
226            /** return text as long */
227            public long toLong() {
228                return Long.parseLong(iText);
229            }
230            
231            /** return text as fouble */
232            public double toDouble() {
233                return Double.parseDouble(iText);
234            }
235            
236            /** return text as boolean */
237            public boolean toBoolean() {
238                return (toInt()!=0);
239            }
240            
241            /** return content as boolean array */
242            public boolean[] toBooleanArray() {
243                if (iContent.size()==1 && iContent.elementAt(0).toString().length()==0) return new boolean[] {};
244                boolean[] ret = new boolean[iContent.size()];
245                for (int i=0;i<ret.length;i++) {
246                    ret[i]=elementAt(i).toBoolean();
247                }
248                return ret;
249            }
250            
251            /** return content as string array */
252            public String[] toStringArray() {
253                if (iContent.size()==1 && iContent.elementAt(0).toString().length()==0) return new String[] {};
254                String[] ret = new String[iContent.size()];
255                for (int i=0;i<ret.length;i++) {
256                    Term t = elementAt(i);
257                    ret[i]=(t.getText().length()>0?t.toString():t.elementAt(0).toString());
258                }
259                return ret;
260            }
261            
262            /** return content as int array */
263            public int[] toIntArray() {
264                //System.err.println("ToIntArray: "+this);
265                if (iContent.size()==1 && iContent.elementAt(0).toString().length()==0) return new int[] {};
266                int[] ret = new int[iContent.size()];
267                for (int i=0;i<ret.length;i++) {
268                    Term t = elementAt(i);
269                    ret[i]=(t.getText().length()>0?Integer.parseInt(t.getText()):t.elementAt(0).toInt());
270                    //System.err.println("  "+i+" .. "+ret[i]);
271                }
272                return ret;
273            }
274            
275            /** idx-th element of content */
276            public Term elementAt(int idx) {
277                try {
278                    return (Term)iContent.elementAt(idx);
279                } catch (Exception e) {
280                    return null;
281                }
282            }
283            
284            /** element of content named name*/
285            public Term element(String name) {
286                try {
287                    for (Enumeration i=iContent.elements();i.hasMoreElements();) {
288                        Term t = (Term)i.nextElement();
289                        if (t.getText()!=null && t.getText().equals(name)) return t;
290                    }
291                    return null;
292                } catch (Exception e) {
293                    return null;
294                }
295            }
296            
297            /** index of element of content named name*/
298            public int indexOf(String name) {
299                try {
300                    int idx=0;
301                    for (Enumeration i=iContent.elements();i.hasMoreElements();) {
302                        Term t = (Term)i.nextElement();
303                        if (t.getText()!=null && t.getText().equals(name)) return idx;
304                        idx++;
305                    }
306                    return -1;
307                } catch (Exception e) {
308                    return -1;
309                }
310            }
311            
312            /** string representation of term */
313            public String toString() {
314                boolean isArray = (iText==null || iText.length()==0);
315                StringBuffer sb = new StringBuffer(isArray?"":iText);
316                if (iContent!=null) {
317                    sb.append(isArray?"[":"(");
318                    for (Enumeration e=iContent.elements();e.hasMoreElements();) {
319                        sb.append(e.nextElement().toString());
320                        sb.append(e.hasMoreElements()?",":"");
321                    }
322                    sb.append(isArray?"]":")");
323                }
324                return sb.toString();
325            }
326            
327            public Object clone() {
328                return new Term(iText==null?null:new String(iText),iContent==null?iContent:(Vector)iContent.clone());
329            }
330        }
331    }