View Javadoc

1   /*
2    * #%L
3    * prolobjectlink-jpi-jpl7
4    * %%
5    * Copyright (C) 2019 Prolobjectlink Project
6    * %%
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions are met:
9    * 
10   * 1. Redistributions of source code must retain the above copyright notice,
11   *    this list of conditions and the following disclaimer.
12   * 2. Redistributions in binary form must reproduce the above copyright notice,
13   *    this list of conditions and the following disclaimer in the documentation
14   *    and/or other materials provided with the distribution.
15   * 
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26   * POSSIBILITY OF SUCH DAMAGE.
27   * #L%
28   */
29  package io.github.prolobjectlink.prolog.jpl7;
30  
31  import static io.github.prolobjectlink.prolog.PrologTermType.LIST_TYPE;
32  
33  import java.util.Iterator;
34  import java.util.NoSuchElementException;
35  
36  import org.jpl7.Compound;
37  import org.jpl7.Query;
38  import org.jpl7.Term;
39  import org.jpl7.Util;
40  
41  import io.github.prolobjectlink.prolog.AbstractIterator;
42  import io.github.prolobjectlink.prolog.PrologList;
43  import io.github.prolobjectlink.prolog.PrologProvider;
44  import io.github.prolobjectlink.prolog.PrologTerm;
45  
46  /**
47   * 
48   * @author Jose Zalacain
49   * @since 1.0
50   */
51  public class JplList extends JplTerm implements PrologList {
52  
53  	public static final Term EMPTY;
54  
55  	static {
56  
57  		Query query = new Query("X=[]");
58  		query.open();
59  		EMPTY = query.getSolution().get("X");
60  		query.close();
61  
62  	}
63  
64  	protected JplList(PrologProvider provider) {
65  		super(LIST_TYPE, provider, EMPTY);
66  	}
67  
68  	protected JplList(PrologProvider provider, Term[] arguments) {
69  		super(LIST_TYPE, provider);
70  		value = EMPTY;
71  		for (int i = arguments.length - 1; i >= 0; --i) {
72  			value = new Compound("[|]", new Term[] { arguments[i], value });
73  		}
74  	}
75  
76  	protected JplList(PrologProvider provider, PrologTerm[] arguments) {
77  		super(LIST_TYPE, provider);
78  		value = EMPTY;
79  		for (int i = arguments.length - 1; i >= 0; --i) {
80  			value = new Compound("[|]", new Term[] { ((JplTerm) arguments[i]).value, value });
81  		}
82  	}
83  
84  	protected JplList(PrologProvider provider, PrologTerm head, PrologTerm tail) {
85  		super(LIST_TYPE, provider);
86  		Term h = ((JplTerm) head).value;
87  		Term t = ((JplTerm) tail).value;
88  		value = new Compound("[|]", new Term[] { h, t });
89  	}
90  
91  	protected JplList(PrologProvider provider, PrologTerm[] arguments, PrologTerm tail) {
92  		super(LIST_TYPE, provider);
93  		value = fromTerm(tail, Term.class);
94  		for (int i = arguments.length - 1; i >= 0; --i) {
95  			Term[] args = { fromTerm(arguments[i], Term.class), value };
96  			value = new Compound("[|]", args);
97  		}
98  	}
99  
100 	public int size() {
101 		return Util.listToLength(value);
102 	}
103 
104 	public void clear() {
105 		value = EMPTY;
106 	}
107 
108 	public boolean isEmpty() {
109 		return value.isListNil();
110 	}
111 
112 	public Iterator<PrologTerm> iterator() {
113 		return new SwiPrologListIter(value);
114 	}
115 
116 	public PrologTerm getHead() {
117 		Compound list = (Compound) value;
118 		return provider.toTerm(list.arg(1), PrologTerm.class);
119 	}
120 
121 	public PrologTerm getTail() {
122 		Compound list = (Compound) value;
123 		return provider.toTerm(list.arg(2), PrologTerm.class);
124 	}
125 
126 	public int getArity() {
127 		return value.arity();
128 	}
129 
130 	public String getFunctor() {
131 		return ".";
132 	}
133 
134 	public PrologTerm[] getArguments() {
135 		return toTermArray(value.toTermArray(), PrologTerm[].class);
136 	}
137 
138 	public String toString() {
139 		StringBuilder string = new StringBuilder("[");
140 		Iterator<PrologTerm> i = iterator();
141 		if (i.hasNext()) {
142 			string.append(i.next());
143 		}
144 		while (i.hasNext()) {
145 			string.append(", ");
146 			string.append(i.next());
147 		}
148 		return string.append("]").toString();
149 	}
150 
151 	private class SwiPrologListIter extends AbstractIterator<PrologTerm> implements Iterator<PrologTerm> {
152 
153 		private Term ptr;
154 		private int index;
155 		private int length;
156 
157 		private SwiPrologListIter(Term l) {
158 			ptr = l;
159 			if (l.isListPair()) {
160 				length = Util.listToLength(l);
161 			}
162 		}
163 
164 		public boolean hasNext() {
165 			return index < length;
166 		}
167 
168 		public PrologTerm next() {
169 
170 			if (!hasNext()) {
171 				throw new NoSuchElementException();
172 			}
173 
174 			PrologTerm term = toTerm(ptr.arg(1), PrologTerm.class);
175 			ptr = ptr.arg(2);
176 			index++;
177 			return term;
178 		}
179 
180 	}
181 
182 }