1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
49
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 }