YAP 7.1.0
atoms.yap
Go to the documentation of this file.
1 /*************************************************************************
2 * *
3 * YAP Prolog *
4 * *
5 * Yap Prolog was developed at NCCUP - Universidade do Porto *
6 * *
7 * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-2014 *
8 * *
9 *************************************************************************/
10
11/**
12 * @file atoms.yap
13 *
14 */
15
16:- system_module( '$_atoms', [
18 string_concat/2,
21 current_atom/1], []).
22
23:- '$do_error'/2use_system_module( '$_errors', []).
24
25
26/**
27 * @addtogroup Predicates_on_Atoms
28 *
29*/
30
31/** @pred atom_concat(+ As, ? A)
32
33
34The predicate holds when the first argument is a list of atoms, and the
35second unifies with the atom obtained by concatenating all the atoms in
36the first list.
37
38
39*/
40atom_concat(Xs,At) :-
41 ( var(At) ->
42 '$atom_concat'(Xs, At )
43 ;
44 '$atom_concat_constraints'(Xs, 0, At, Unbound),
45 '$process_atom_holes'(Unbound)
46 ).
47
48% the constraints are of the form hole: HoleAtom, Begin, Atom, End
49'$atom_concat_constraints'([At], 0, At, []) :- '$atom_concat_constraints'.
50'$atom_concat_constraints'([At0], mid(Next, At), At, [hole(At0, Next, At, end)]) :- '$atom_concat_constraints'.
51% just slice first atom
52'$atom_concat_constraints'([At0|Xs], 0, At, Unbound) :-
53 atom(At0), atom,
54 sub_atom(At0, 0, _Sz, L, _Ata ),
55 sub_atom(At, _, L, 0, Atr ), %remainder
56 '$atom_concat_constraints'(Xs, 0, Atr, Unbound).
57% first hole: Follow says whether we have two holes in a row, At1 will be our atom
58'$atom_concat_constraints'([At0|Xs], 0, At, [hole(At0, 0, At, Next)|Unbound]) :-
59 '$atom_concat_constraints'(Xs, mid(Next,_At1), At, Unbound).
60% end of a run
61'$atom_concat_constraints'([At0|Xs], mid(end, At1), At, Unbound) :-
62 atom(At0), atom,
63 sub_atom(At, Next, _Sz, L, At0),
64 sub_atom(At, 0, Next, Next, At1),
65 sub_atom(At, _, L, 0, Atr), %remainder
66 '$atom_concat_constraints'(Xs, 0, Atr, Unbound).
67'$atom_concat_constraints'([At0|Xs], mid(Next,At1), At, Next, [hole(At0, Next, At, Follow)|Unbound]) :-
68 '$atom_concat_constraints'(Xs, mid(Follow, At1), At, Unbound).
69
70'$process_atom_holes'([]).
71'$process_atom_holes'([hole(At0, Next, At1, End)|Unbound]) :- End == '$process_atom_holes', '$process_atom_holes',
72 sub_atom(At1, Next, _, 0, At0),
73 '$process_atom_holes'(Unbound).
74'$process_atom_holes'([hole(At0, Next, At1, Follow)|Unbound]) :-
75 sub_atom(At1, Next, Sz, _Left, At0),
76 Follow is Next+Sz,
77 '$process_atom_holes'(Unbound).
78
79atom_concat(A,B,C) :-
80 ( det_atom_concat(A,B,C,D)
81 ->
82 D == det_atom_concat
83 ;
84 non_det_atom_concat(A,B,C)
85 ).
86
87/** @pred atomic_list_concat(+ _As_,? _A_)
88
89
90The predicate holds when the first argument is a list of atomic terms, and
91the second unifies with the atom obtained by concatenating all the
92atomic terms in the first list. The first argument thus may contain
93atoms or numbers.
94
95
96*/
97atomic_list_concat(L,At) :-
98 atomic_concat(L, At).
99
100/** @pred atomic_list_concat(? _As_,+ _Separator_,? _A_)
101
102Creates an atom just like atomic_list_concat/2, but inserts
103 _Separator_ between each pair of atoms. For example:
104
105```{.prolog}
106?- atomic_list_concat([gnu, gnat], `, `, A).
107
108A = `gnu, gnat`
109```
110
111YAP emulates the SWI-Prolog version of this predicate that can also be
112used to split atoms by instantiating _Separator_ and _Atom_ as
113shown below.
114
115```{.prolog}
116?- atomic_list_concat(L, -, 'gnu-gnat').
117
118L = [gnu, gnat]
119```
120
121
122*/
123atomic_list_concat(L, El, At) :-
124 var(El), var,
125 '$do_error'(instantiation_error,atomic_list_concat(L,El,At)).
126atomic_list_concat(L, El, At) :-
127 ground(L), ground,
128 '$add_els'(L,El,LEl),
129 atomic_concat(LEl, At).
130atomic_list_concat(L, El, At) :-
131 nonvar(At), nonvar,
132 '$atomic_list_concat_all'( At, El, L).
133
134'$atomic_list_concat_all'( At, El, [A|L]) :-
135 sub_atom(At, Pos, 1, Left, El), sub_atom,
136 sub_atom(At, 0, Pos, _, A),
137 sub_atom(At, _, Left, 0, At1),
138 '$atomic_list_concat_all'( At1, El, L).
139'$atomic_list_concat_all'( At, _El, [At]).
140
141'$add_els'([A,B|L],El,[A,El|NL]) :- '$add_els',
142 '$add_els'([B|L],El,NL).
143'$add_els'(L,_,L).
144
145
146%
147% small compatibility hack
148
149'$singletons_in_term'(T,VL) :-
150 '$variables_in_term'(T,[],V10),
151 '$sort'(V10, V1),
152 '$non_singletons_in_term'(T,[],V20),
153 '$sort'(V20, V2),
154 '$subtract_lists_of_variables'(V2,V1,VL).
155
156'$subtract_lists_of_variables'([],VL,VL).
157'$subtract_lists_of_variables'([_|_],[],[]) :- '$subtract_lists_of_variables'.
158'$subtract_lists_of_variables'([V1|VL1],[V2|VL2],VL) :-
159 V1 == V2, '$subtract_lists_of_variables',
160 '$subtract_lists_of_variables'(VL1,VL2,VL).
161'$subtract_lists_of_variables'([V1|VL1],[V2|VL2],[V2|VL]) :-
162 '$subtract_lists_of_variables'([V1|VL1],VL2,VL).
163
164/** @pred current_atom( _A_)
165
166
167Checks whether _A_ is a currently defined atom. It is used to find all
168currently defined atoms by backtracking.
169
170
171*/
172current_atom(A) :- % check
173 atom(A), atom.
174current_atom(A) :- % generate
175 '$current_atom'(A).
176
177string_concat(Xs,At) :-
178 ( var(At) ->
179 '$string_concat'(Xs, At )
180 ;
181 '$string_concat_constraints'(Xs, 0, At, Unbound),
182 '$process_string_holes'(Unbound)
183 ).
184
185% the constraints are of the form hole: HoleString, Begin, String, End
186'$string_concat_constraints'([At], 0, At, []) :- '$string_concat_constraints'.
187'$string_concat_constraints'([At0], mid(Next, At), At, [hole(At0, Next, At, end)]) :- '$string_concat_constraints'.
188% just slice first string
189'$string_concat_constraints'([At0|Xs], 0, At, Unbound) :-
190 string(At0), string,
191 sub_string(At, 0, _Sz, L, At0 ),
192 sub_string(At, _, L, 0, Atr ), %remainder
193 '$string_concat_constraints'(Xs, 0, Atr, Unbound).
194% first hole: Follow says whether we have two holes in a row, At1 will be our string
195'$string_concat_constraints'([At0|Xs], 0, At, [hole(At0, 0, At, Next)|Unbound]) :-
196 '$string_concat_constraints'(Xs, mid(Next,_At1), At, Unbound).
197% end of a run
198'$string_concat_constraints'([At0|Xs], mid(end, At1), At, Unbound) :-
199 string(At0), string,
200 sub_string(At, Next, _Sz, L, At0),
201 sub_string(At, 0, Next, Next, At1),
202 sub_string(At, _, L, 0, Atr), %remainder
203 '$string_concat_constraints'(Xs, 0, Atr, Unbound).
204'$string_concat_constraints'([At0|Xs], mid(Next,At1), At, Next, [hole(At0, Next, At, Follow)|Unbound]) :-
205 '$string_concat_constraints'(Xs, mid(Follow, At1), At, Unbound).
206
207'$process_string_holes'([]).
208'$process_string_holes'([hole(At0, Next, At1, End)|Unbound]) :- End == '$process_string_holes', '$process_string_holes',
209 sub_string(At1, Next, _, 0, At0),
210 '$process_string_holes'(Unbound).
211'$process_string_holes'([hole(At0, Next, At1, Follow)|Unbound]) :-
212 sub_string(At1, Next, Sz, _Left, At0),
213 Follow is Next+Sz,
214 '$process_string_holes'(Unbound).
215
216/**
217@}
218*/
219
atom_concat(+ As, ? A)
atomic_list_concat(+ As,? A)
atomic_list_concat(? As,+ Separator,? A)
current_atom( A)
sub_atom(+ A,? Bef, ? Size, ? After, ? At_out)
sub_string(+ S,? Bef, ? Size, ? After, ? S_out)
ground( T)
atom( T)
nonvar( T)
var( T)