forked from xicoVale/yap-6.3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
arg.yap
165 lines (131 loc) · 3.32 KB
/
arg.yap
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/**
* @file arg.yap
* @author VITOR SANTOS COSTA <[email protected]>
* @date Tue Nov 17 01:08:55 2015
*
* @brief arg/3 and friends
*/
:- module(arg,
[
genarg/3,
arg0/3,
genarg0/3,
args/3,
args0/3,
% project/3
path_arg/3
]).
/**
* @defgroup arg Term Argument Manipulation.
@ingroup @library
@{
Extends arg/3 by including backtracking through arguments and access
to sub-arguments,
- arg0/3
- args/3
- args0/3
- genarg/3
- genarg0/3
- path_arg/3
It is based on the Quintus Prolog arg library. Except for project, all
predicates use the arg/3 argument pattern.
This file has been included in the YAP library by Vitor Santos Costa, 2008. No error checking is actuallly performed within the package: this left to the C-code thaat implements arg/3 and
genarg/3.
*/
/**
* @pred arg0( +_Index_, +_Term_ , -_Arg_ )
*
* Similar to arg/3, but `arg0(0,_T_,_F_)` unifies _F_ with _T_'s principal functor:
~~~~~~~~~
?- arg0(0, f(a,b), A).
A = f.
?- arg0(1, f(a,b), A).
A = a.
?- arg0(2, f(a,b), A).
A = b.
~~~~~~~~~
*/
arg0(0,T,A) :- !,
functor(T,A,_).
arg0(I,T,A) :-
arg(I,T,A).
/**
* @pred genarg0( +_Index_, +_Term_ , -_Arg_ )
*
* Similar to genarg/3, but `genarg0(0,_T_,_F_)` unifies _F_ with _T_'s principal functor:
~~~~~~~~~
?- genarg0(I,f(a,b),A).
A = f,
I = 0 ? ;
A = a,
I = 1 ? ;
A = b,
I = 2.
~~~~~~~~~
*/
genarg0(I,T,A) :-
nonvar(I), !,
arg0(I,T,A).
genarg0(0,T,A) :-
functor(T,A,_).
genarg0(I,T,A) :-
genarg(I,T,A).
/**
* @pred args( +_Index_, +_ListOfTerms_ , -_ListOfArgs_ )
*
* Succeeds if _ListOfArgs_ unifies with the application of genarg/3 to every element of _ListOfTerms_.
It corresponds to calling maplist/3 on genarg/3:
~~~~~~~~~
args( I, Ts, As) :-
maplist( genarg(I), Ts, As).
~~~~~~~~~
Notice that unification allows _ListOfArgs_ to be bound, eg:
~~~~~~~~~
?- args(1, [X1+Y1,X2-Y2,X3*Y3,X4/Y4], [1,1,1,1]).
X1 = X2 = X3 = X4 = 1.
~~~~~~~~~
*/
args(_,[],[]).
args(I,[T|List],[A|ArgList]) :-
genarg(I, T, A),
args(I, List, ArgList).
/**
* @pred args0( +_Index_, +_ListOfTerms_ , -_ListOfArgs_ )
*
* Succeeds if _ListOfArgs_ unifies with the application of genarg0/3 to every element of _ListOfTerms_.
It corresponds to calling maplist/3 on genarg0/3:
~~~~~~~~~
args( I, Ts, As) :-
maplist( genarg0(I), Ts, As).
~~~~~~~~~
Notice that unification allows _ListOfArgs_ to be bound, eg:
~~~~~~~~~
?- args(1, [X1+Y1,X2-Y2,X3*Y3,X4/Y4], [1,1,1,1]).
X1 = X2 = X3 = X4 = 1.
~~~~~~~~~
*/
args0(_,[],[]).
args0(I,[T|List],[A|ArgList]) :-
genarg(I, T, A),
args0(I, List, ArgList).
/**
* @pred args0( +_ListOfTerms_ , +_Index_, -_ListOfArgs_ )
*
* Succeeds if _ListOfArgs_ unifies with the application of genarg0/3 to every element of _ListOfTerms_.
It corresponds to calling args0/3 but with a different order.
*/
project(Terms, Index, Args) :-
args0(Index, Terms, Args).
% no error checking here!
/**
* @pred path_arg( +_Path_ , +_Term_, -_Arg_ )
*
* Succeeds if _Path_ is empty and _Arg unifies with _Term_, or if _Path_ is a list with _Head_ and _Tail_, genarg/3 succeeds on the current term, and path_arg/3 succeeds on its argument.
*
* Notice that it can be used to enumerate all possible paths in a term.
*/
path_arg([], Term, Term).
path_arg([Index|Indices], Term, SubTerm) :-
genarg(Index, Term, Arg),
path_arg(Indices, Arg, SubTerm).
%%@}