| 1 | |
|---|
| 2 | :- object(difflist, |
|---|
| 3 | implements(listp), |
|---|
| 4 | extends(compound)). |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | :- info([ |
|---|
| 8 | version is 1.1, |
|---|
| 9 | author is 'Paulo Moura', |
|---|
| 10 | date is 2004/5/9, |
|---|
| 11 | comment is 'Difference list predicates.']). |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | :- public(as_list/2). |
|---|
| 15 | |
|---|
| 16 | :- mode(as_list(+list, -list), one). |
|---|
| 17 | |
|---|
| 18 | :- info(as_list/2, |
|---|
| 19 | [comment is 'Converts a difference list to a normal list.', |
|---|
| 20 | argnames is ['Diffist', 'List']]). |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | append(List1-Back1, Back1-Back2, List1-Back2) :- |
|---|
| 24 | nonvar(List1), |
|---|
| 25 | nonvar(Back1), |
|---|
| 26 | !. |
|---|
| 27 | |
|---|
| 28 | append(Prefix, Suffix, List) :- |
|---|
| 29 | length(List, Length), |
|---|
| 30 | prefix(Prefix, List), |
|---|
| 31 | length(Prefix, PLength), |
|---|
| 32 | SLength is Length - PLength, |
|---|
| 33 | length(Suffix, SLength), |
|---|
| 34 | suffix(Suffix, List). |
|---|
| 35 | |
|---|
| 36 | |
|---|
| 37 | as_list(List-Back, Out) :- |
|---|
| 38 | List == Back -> |
|---|
| 39 | Out = [] |
|---|
| 40 | ; |
|---|
| 41 | Out = [Head| Tail], |
|---|
| 42 | List = [Head| Rest], |
|---|
| 43 | as_list(Rest-Back, Tail). |
|---|
| 44 | |
|---|
| 45 | |
|---|
| 46 | delete(List-Back, Element, Remaining) :- |
|---|
| 47 | List == Back -> |
|---|
| 48 | unify_with_occurs_check(Remaining, Back-Back) |
|---|
| 49 | ; |
|---|
| 50 | List \== Back, |
|---|
| 51 | List = [Head| Tail], |
|---|
| 52 | (Head == Element -> |
|---|
| 53 | delete(Tail-Back, Element, Remaining) |
|---|
| 54 | ; |
|---|
| 55 | Remaining = [Head| Tail2], |
|---|
| 56 | delete(Tail-Back, Element, Tail2-Back)). |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | |
|---|
| 60 | delete_matches(List-Back, Element, Remaining) :- |
|---|
| 61 | List == Back -> |
|---|
| 62 | unify_with_occurs_check(Remaining, Back-Back) |
|---|
| 63 | ; |
|---|
| 64 | List \== Back, |
|---|
| 65 | List = [Head| Tail], |
|---|
| 66 | (\+ \+ Head = Element -> |
|---|
| 67 | delete_matches(Tail-Back, Element, Remaining) |
|---|
| 68 | ; |
|---|
| 69 | Remaining = [Head| Tail2], |
|---|
| 70 | delete_matches(Tail-Back, Element, Tail2-Back)). |
|---|
| 71 | |
|---|
| 72 | |
|---|
| 73 | empty(List-Back) :- |
|---|
| 74 | List == Back. |
|---|
| 75 | |
|---|
| 76 | |
|---|
| 77 | flatten(List-Back, Flatted-Back) :- |
|---|
| 78 | flatten(List-Back, Back-Back, Flatted-Back). |
|---|
| 79 | |
|---|
| 80 | |
|---|
| 81 | flatten(Var, Tail-Back, [Var| Tail]-Back) :- |
|---|
| 82 | var(Var), |
|---|
| 83 | !. |
|---|
| 84 | |
|---|
| 85 | flatten(List-Back, Flatted, Flatted) :- |
|---|
| 86 | List == Back, |
|---|
| 87 | !. |
|---|
| 88 | |
|---|
| 89 | flatten(List-Back, Acc, Flatted) :- |
|---|
| 90 | !, |
|---|
| 91 | List \== Back, |
|---|
| 92 | List = [Head| Tail], |
|---|
| 93 | flatten(Tail-Back, Acc, Acc2), |
|---|
| 94 | flatten(Head, Acc2, Flatted). |
|---|
| 95 | |
|---|
| 96 | flatten(Head, Tail-Back, [Head| Tail]-Back). |
|---|
| 97 | |
|---|
| 98 | |
|---|
| 99 | keysort(Difflist, Sorted) :- |
|---|
| 100 | as_list(Difflist, List), |
|---|
| 101 | {keysort(List, List2)}, |
|---|
| 102 | list::as_difflist(List2, Sorted). |
|---|
| 103 | |
|---|
| 104 | |
|---|
| 105 | last(List-Back, Last) :- |
|---|
| 106 | List \== Back, |
|---|
| 107 | List = [Head| Tail], |
|---|
| 108 | last(Tail-Back, Head, Last). |
|---|
| 109 | |
|---|
| 110 | |
|---|
| 111 | last(List, Last, Last) :- |
|---|
| 112 | unify_with_occurs_check(List, Back-Back). |
|---|
| 113 | |
|---|
| 114 | last(List-Back, _, Last) :- |
|---|
| 115 | List \== Back, |
|---|
| 116 | List = [Head| Tail], |
|---|
| 117 | last(Tail-Back, Head, Last). |
|---|
| 118 | |
|---|
| 119 | |
|---|
| 120 | length(List, Length) :- |
|---|
| 121 | integer(Length) -> |
|---|
| 122 | Length >= 0, |
|---|
| 123 | make_list(Length, List) |
|---|
| 124 | ; |
|---|
| 125 | length(List, 0, Length). |
|---|
| 126 | |
|---|
| 127 | |
|---|
| 128 | length(List, Length, Length) :- |
|---|
| 129 | unify_with_occurs_check(List, Back-Back). |
|---|
| 130 | |
|---|
| 131 | length(List-Back, Acc, Length) :- |
|---|
| 132 | List \== Back, |
|---|
| 133 | List = [_| Tail], |
|---|
| 134 | Acc2 is Acc + 1, |
|---|
| 135 | length(Tail-Back, Acc2, Length). |
|---|
| 136 | |
|---|
| 137 | |
|---|
| 138 | make_list(0, List):- |
|---|
| 139 | !, |
|---|
| 140 | unify_with_occurs_check(List, Back-Back). |
|---|
| 141 | |
|---|
| 142 | make_list(N, List-Back):- |
|---|
| 143 | List \== Back, |
|---|
| 144 | List = [_| Tail], |
|---|
| 145 | M is N-1, |
|---|
| 146 | make_list(M, Tail-Back). |
|---|
| 147 | |
|---|
| 148 | |
|---|
| 149 | max(List-Back, Max) :- |
|---|
| 150 | List \== Back, |
|---|
| 151 | List = [Head| Tail], |
|---|
| 152 | max(Tail-Back, Head, Max). |
|---|
| 153 | |
|---|
| 154 | |
|---|
| 155 | max(List-Back, Max, Max) :- |
|---|
| 156 | List == Back, !. |
|---|
| 157 | |
|---|
| 158 | max(List-Back, Aux, Max) :- |
|---|
| 159 | List \== Back, |
|---|
| 160 | List = [Head| Tail], |
|---|
| 161 | (Aux @< Head -> |
|---|
| 162 | max(Tail-Back, Head, Max) |
|---|
| 163 | ; |
|---|
| 164 | max(Tail-Back, Aux, Max)). |
|---|
| 165 | |
|---|
| 166 | |
|---|
| 167 | member(Element, List-Back) :- |
|---|
| 168 | List \== Back, |
|---|
| 169 | List = [Element|_]. |
|---|
| 170 | |
|---|
| 171 | member(Element, List-Back) :- |
|---|
| 172 | List \== Back, |
|---|
| 173 | List = [_| Tail], |
|---|
| 174 | member(Element, Tail-Back). |
|---|
| 175 | |
|---|
| 176 | |
|---|
| 177 | memberchk(Element, List) :- |
|---|
| 178 | once(member(Element, List)). |
|---|
| 179 | |
|---|
| 180 | |
|---|
| 181 | nth0(Position, List, Element) :- |
|---|
| 182 | nth(Element, List, 0, Position, _). |
|---|
| 183 | |
|---|
| 184 | |
|---|
| 185 | nth0(Nth, List, Element, Tail) :- |
|---|
| 186 | nth(Element, List, 0, Nth, Tail). |
|---|
| 187 | |
|---|
| 188 | |
|---|
| 189 | nth1(Position, List, Element) :- |
|---|
| 190 | nth(Element, List, 1, Position, _). |
|---|
| 191 | |
|---|
| 192 | |
|---|
| 193 | nth1(Nth, List, Element, Tail) :- |
|---|
| 194 | nth(Element, List, 1, Nth, Tail). |
|---|
| 195 | |
|---|
| 196 | |
|---|
| 197 | nth(Element, List-Back, Position, Position, Tail-Back) :- |
|---|
| 198 | List \== Back, |
|---|
| 199 | List = [Element| Tail]. |
|---|
| 200 | |
|---|
| 201 | nth(Element, List-Back, Count, Position, Tail-Back) :- |
|---|
| 202 | List \== Back, |
|---|
| 203 | List = [_| List2], |
|---|
| 204 | Count2 is Count + 1, |
|---|
| 205 | nth(Element, List2-Back, Count2, Position, Tail-Back). |
|---|
| 206 | |
|---|
| 207 | |
|---|
| 208 | min(List-Back, Min) :- |
|---|
| 209 | List \== Back, |
|---|
| 210 | List = [Head| Tail], |
|---|
| 211 | min(Tail-Back, Head, Min). |
|---|
| 212 | |
|---|
| 213 | |
|---|
| 214 | min(List-Back, Min, Min) :- |
|---|
| 215 | List == Back, !. |
|---|
| 216 | |
|---|
| 217 | min(List-Back, Aux, Min) :- |
|---|
| 218 | List \== Back, |
|---|
| 219 | List = [Head| Tail], |
|---|
| 220 | (Head @< Aux -> |
|---|
| 221 | min(Tail-Back, Head, Min) |
|---|
| 222 | ; |
|---|
| 223 | min(Tail-Back, Aux, Min)). |
|---|
| 224 | |
|---|
| 225 | |
|---|
| 226 | new(List) :- |
|---|
| 227 | unify_with_occurs_check(List, Back-Back). |
|---|
| 228 | |
|---|
| 229 | |
|---|
| 230 | permutation(List, Permutation) :- |
|---|
| 231 | same_length(List, Permutation), |
|---|
| 232 | permutation2(List, Permutation). |
|---|
| 233 | |
|---|
| 234 | |
|---|
| 235 | permutation2(List1-Back1, List2-Back2) :- |
|---|
| 236 | List1 == Back1, |
|---|
| 237 | List2 == Back2. |
|---|
| 238 | |
|---|
| 239 | permutation2(List1-Back1, List2-Back2) :- |
|---|
| 240 | List2 \== Back2, |
|---|
| 241 | List2 = [Head2| Tail2], |
|---|
| 242 | select(Head2, List1-Back1, Tail1-Back1), |
|---|
| 243 | permutation2(Tail1-Back1, Tail2-Back2). |
|---|
| 244 | |
|---|
| 245 | |
|---|
| 246 | prefix(List, _) :- |
|---|
| 247 | unify_with_occurs_check(List, Back-Back). |
|---|
| 248 | |
|---|
| 249 | prefix(List-Back, List2-Back2) :- |
|---|
| 250 | List \== Back, |
|---|
| 251 | List = [Head| Tail], |
|---|
| 252 | List2 \== Back2, |
|---|
| 253 | List2 = [Head| Tail2], |
|---|
| 254 | prefix(Tail-Back, Tail2-Back2). |
|---|
| 255 | |
|---|
| 256 | |
|---|
| 257 | reverse(List-Back, Reversed-Back) :- |
|---|
| 258 | same_length(List-Back, Reversed-Back), |
|---|
| 259 | reverse(List-Back, Back-Back, Reversed-Back). |
|---|
| 260 | |
|---|
| 261 | |
|---|
| 262 | reverse(List-Back, Reversed, Reversed) :- |
|---|
| 263 | List == Back. |
|---|
| 264 | |
|---|
| 265 | reverse(List-Back, Acc-Back, Reversed) :- |
|---|
| 266 | List \== Back, |
|---|
| 267 | List = [Head| Tail], |
|---|
| 268 | reverse(Tail-Back, [Head| Acc]-Back, Reversed). |
|---|
| 269 | |
|---|
| 270 | |
|---|
| 271 | same_length(List1, List2) :- |
|---|
| 272 | unify_with_occurs_check(List1, Back1-Back1), |
|---|
| 273 | unify_with_occurs_check(List2, Back2-Back2). |
|---|
| 274 | |
|---|
| 275 | same_length(List1-Back1, List2-Back2) :- |
|---|
| 276 | List1 \== Back1, |
|---|
| 277 | List1 = [_| Tail1], |
|---|
| 278 | List2 \== Back2, |
|---|
| 279 | List2 = [_| Tail2], |
|---|
| 280 | same_length(Tail1-Back1, Tail2-Back2). |
|---|
| 281 | |
|---|
| 282 | |
|---|
| 283 | select(Head, List-Back, Tail-Back) :- |
|---|
| 284 | List \== Back, |
|---|
| 285 | List = [Head| Tail]. |
|---|
| 286 | |
|---|
| 287 | select(Head, List-Back, List2-Back) :- |
|---|
| 288 | List \== Back, |
|---|
| 289 | List = [Other| Tail], |
|---|
| 290 | List2 \== Back, |
|---|
| 291 | List2 = [Other| Tail2], |
|---|
| 292 | select(Head, Tail-Back, Tail2-Back). |
|---|
| 293 | |
|---|
| 294 | |
|---|
| 295 | sort(Difflist, Sorted) :- |
|---|
| 296 | as_list(Difflist, List), |
|---|
| 297 | {sort(List, List2)}, |
|---|
| 298 | list::as_difflist(List2, Sorted). |
|---|
| 299 | |
|---|
| 300 | |
|---|
| 301 | sublist(Sublist, List) :- |
|---|
| 302 | unify_with_occurs_check(Sublist, List). |
|---|
| 303 | |
|---|
| 304 | sublist(Sublist-Back, List-Back):- |
|---|
| 305 | List \== Back, |
|---|
| 306 | List = [Head| Tail], |
|---|
| 307 | sublist(Tail-Back, Head, Sublist-Back). |
|---|
| 308 | |
|---|
| 309 | |
|---|
| 310 | sublist(List, _, Sublist) :- |
|---|
| 311 | unify_with_occurs_check(List, Sublist). |
|---|
| 312 | |
|---|
| 313 | sublist(List-Back, _, Sublist-Back):- |
|---|
| 314 | List \== Back, |
|---|
| 315 | List = [Head| Tail], |
|---|
| 316 | sublist(Tail-Back, Head, Sublist-Back). |
|---|
| 317 | |
|---|
| 318 | sublist(List-Back, Element, [Element| Sublist]-Back):- |
|---|
| 319 | List \== Back, |
|---|
| 320 | List = [Head| Tail], |
|---|
| 321 | sublist(Tail-Back, Head, Sublist-Back). |
|---|
| 322 | |
|---|
| 323 | |
|---|
| 324 | subtract(List-Back, _, Result) :- |
|---|
| 325 | unify_with_occurs_check(Result, Back-Back), |
|---|
| 326 | List == Back, !. |
|---|
| 327 | |
|---|
| 328 | subtract(List-Back, Ys, List2-Back) :- |
|---|
| 329 | List \== Back, |
|---|
| 330 | List = [Head| Tail], |
|---|
| 331 | (member(Head, Ys) -> |
|---|
| 332 | subtract(Tail-Back, Ys, List2-Back) |
|---|
| 333 | ; |
|---|
| 334 | List2 = [Head| Tail2], |
|---|
| 335 | subtract(Tail-Back, Ys, Tail2-Back)). |
|---|
| 336 | |
|---|
| 337 | |
|---|
| 338 | suffix(Suffix, List) :- |
|---|
| 339 | unify_with_occurs_check(Suffix, List). |
|---|
| 340 | |
|---|
| 341 | suffix(Suffix-Back, List-Back) :- |
|---|
| 342 | List \== Back, |
|---|
| 343 | List = [_| Tail], |
|---|
| 344 | suffix(Suffix-Back, Tail-Back). |
|---|
| 345 | |
|---|
| 346 | |
|---|
| 347 | valid(List) :- |
|---|
| 348 | nonvar(List), |
|---|
| 349 | valid2(List). |
|---|
| 350 | |
|---|
| 351 | |
|---|
| 352 | valid2(List-Back) :- |
|---|
| 353 | List == Back, |
|---|
| 354 | !. |
|---|
| 355 | |
|---|
| 356 | valid2(List-Back) :- |
|---|
| 357 | nonvar(List), |
|---|
| 358 | List = [_| Tail], |
|---|
| 359 | valid2(Tail-Back). |
|---|
| 360 | |
|---|
| 361 | |
|---|
| 362 | :- end_object. |
|---|