YAP
7.1.0
coinduction.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-1997 *
8
* *
9
**************************************************************************
10
* *
11
* File: coinduction.yap *
12
* Last rev: 8/2/88 *
13
* mods: *
14
* comments: coinduction support for Prolog *
15
* *
16
*************************************************************************/
17
18
/**
19
* @file coinduction.yap
20
* @author VITOR SANTOS COSTA <vsc@VITORs-MBP.lan>, Arvin Bansal,
21
* @author Includes nice extensions from Jan Wielemaker (from the SWI version). *
22
*
23
* @date Tue Nov 17 14:55:02 2015
24
*
25
* @brief Co-inductive execution
26
*
27
*
28
*/
29
30
/**
31
* @defgroup coinduction Co-Logic Programming
32
* @ingroup YAPLibrary
33
* @{
34
*
35
*/
36
37
% :- yap_flag(unknown,error).
38
% :- style_check(all).
39
40
41
:- module(
coinduction
,
42
[ (coinductive)
/
1
,
43
op(
1150
, fx, (coinductive))
44
]).
45
46
:-
use_module
(library(error)).
47
48
/**
49
50
@addtogroup coinduction Co-induction
51
@ingroup YAPLibrary
52
@{
53
54
55
This simple module implements the directive coinductive/1 as described
56
in "Co-Logic Programming: Extending Logic Programming with Coinduction"
57
by Luke Somin et al. The idea behind coinduction is that a goal succeeds
58
if it unifies to a parent goal. This enables some interesting programs,
59
notably on infinite trees (cyclic terms).
60
61
```
62
:- use_module(library(coinduction)).
63
64
:- coinductive stream/1.
65
stream([H|T]) :- i(H), stream(T).
66
67
% inductive
68
i(0).
69
i(s(N)) :- i(N).
70
71
?- X=[s(s(A))|X], stream(X).
72
X= [s(s(A))|X], stream(X).
73
A = 0,
74
X = [s(s(0)),**]
75
```
76
77
This predicate is true for any cyclic list containing only 1-s,
78
regardless of the cycle-length.
79
80
`@bug` Programs mixing normal predicates and coinductive predicates must
81
be _stratified_. The theory does not apply to normal Prolog calling
82
coinductive predicates, calling normal Prolog predicates, etc.
83
84
Stratification is not checked or enforced in any other way and thus
85
left as a responsibility to the user.
86
`@see` "Co-Logic Programming: Extending Logic Programming with Coinduction"
87
by Luke Somin et al.
88
89
*/
90
91
:-
meta_predicate
coinductive(
:
).
92
93
:-
dynamic
coinductive/3.
94
95
96
%-----------------------------------------------------
97
98
coinductive(
Spec
)
:-
99
var
(
Spec
),
100
var,
101
throw
(error(instantiation_error,coinductive(
Spec
))).
102
coinductive(
Module
:
Spec
)
:-
103
coinductive_declaration(
Spec
,
Module
, coinductive(
Module
:
Spec
)).
104
coinductive(
Spec
)
:-
105
prolog_load_context
(module,
Module
),
106
coinductive_declaration(
Spec
,
Module
, coinductive(
Spec
)).
107
108
coinductive_declaration(
Spec
,
_M
,
G
)
:-
109
var
(
Spec
),
110
var,
111
throw
(error(instantiation_error,
G
)).
112
coinductive_declaration((
A
,
B
),
M
,
G
)
:-
coinductive_declaration,
113
coinductive_declaration(
A
,
M
,
G
),
114
coinductive_declaration(
B
,
M
,
G
).
115
coinductive_declaration(
M
:
Spec
,
_
,
G
)
:-
coinductive_declaration,
116
coinductive_declaration(
Spec
,
M
,
G
).
117
coinductive_declaration(
Spec
,
M
,
_G
)
:-
118
valid_pi(
Spec
,
F
,
N
),
119
functor
(
S
,
F
,
N
),
120
atomic_concat([
'__coinductive__'
,
F
,
'/'
,
N
],
NF
),
121
functor
(
NS
,
NF
,
N
),
122
match_args(
N
,
S
,
NS
),
123
atomic_concat([
'__stack_'
,
M
,
':'
,
F
,
'/'
,
N
],
SF
),
124
nb_setval
(
SF
,
_
),
125
assert
((
M
:
S
:-
126
b_getval(
SF
,
L
),
127
coinduction
:
in_stack(
S
,
L
,
End
),
128
(
129
nonvar(
End
)
130
->
131
true
132
;
133
End
=
[
S
|
_
],
134
M
:
NS
)
135
)
136
),
137
assert
(coinduction
:
coinductive(
S
,
M
,
NS
)).
138
139
valid_pi(
Name
/
Arity
,
Name
,
Arity
)
:-
140
must_be(atom,
Name
),
141
must_be(integer,
Arity
).
142
143
match_args(
0
,
_
,
_
)
:-
match_args.
144
match_args(
I
,
S1
,
S2
)
:-
145
arg
(
I
,
S1
,
A
),
146
arg
(
I
,
S2
,
A
),
147
I1
is
I
-
1
,
148
match_args(
I1
,
S1
,
S2
).
149
150
%-----------------------------------------------------
151
152
co_term_expansion((
M
:
H
:-
B
),
_
, (
M
:
NH
:-
B
))
:-
co_term_expansion,
153
co_term_expansion((
H
:-
B
),
M
, (
NH
:-
B
)).
154
co_term_expansion((
H
:-
B
),
M
, (
NH
:-
B
))
:-
co_term_expansion,
155
coinductive(
H
,
M
,
NH
),
coinductive.
156
co_term_expansion(
H
,
M
,
NH
)
:-
157
coinductive(
H
,
M
,
NH
),
coinductive.
158
159
/** user:term_expansion(+M:Cl,-M:NCl )
160
161
rule preprocessor
162
*/
163
coinductive
:
term_expansion
(
M
:
Cl
,
M
:
NCl
)
:-
term_expansion,
164
co_term_expansion(
Cl
,
M
,
NCl
).
165
166
co_term_expansion
:
term_expansion
(
G
,
NG
)
:-
167
prolog_load_context
(module,
Module
),
168
co_term_expansion(
G
,
Module
,
NG
).
169
170
171
%-----------------------------------------------------
172
173
in_stack(
_
,
V
,
V
)
:-
var
(
V
),
var.
174
in_stack(
G
, [
G
|
_
], [
G
|
_
])
:-
in_stack.
175
in_stack(
G
, [
_
|
T
],
End
)
:-
in_stack(
G
,
T
,
End
).
176
177
writeG_val(
G_var
)
:-
178
b_getval
(
G_var
,
G_val
),
179
write(
G_var
),
write(
' ==> '
),
write(
G_val
),
write.
180
181
%-----------------------------------------------------
182
183
/**
184
185
Some examples from Coinductive Logic Programming and its Applications by Gopal Gupta et al, ICLP 97
186
187
```
188
:- coinductive stream/1.
189
stream([H|T]) :- i(H), stream(T).
190
191
% inductive
192
i(0).
193
i(s(N)) :- i(N).
194
195
% Are there infinitely many "occurrences" of arg1 in arg2?
196
:- coinductive comember/2.
197
198
comember(X, L) :-
199
drop(X, L, L1),
200
comember(X, L1).
201
202
% Drop some prefix of arg2 upto an "occurrence" of arg1 from arg2,
203
% yielding arg3.
204
% ("Occurrence" of X = something unifiable with X.)
205
%:- table(drop/3). % not working; needs tabling supporting cyclic terms!
206
drop(H, [H| T], T).
207
drop(H, [_| T], T1) :-
208
drop(H, T, T1).
209
210
211
% X = [1, 2, 3| X], comember(E, X).
212
213
user:p(E) :-
214
X = [1, 2, 3| X],
215
comember(E, X),
216
format('~w~n',[E]),
217
get_code(_),
218
fail.
219
220
221
222
```
223
*/
224
225
/**
226
@}
227
*/
228
229
throw/1
throw(+ Ball)
assert/1
assert(+ C)
nb_setval/2
nb_setval(+ Name,+ Value)
use_module/1
use_module( +Files )
term_expansion/2
term_expansion( T,- X)
b_getval/2
b_getval(+ Name, - Value)
prolog_load_context/2
prolog_load_context(? Key, ? Value)
Definition:
consult.yap:479
arg/3
arg(+ N,+ T, A)
functor/3
functor( T, F, N)
var/1
var( T)
library
coinduction.yap
Generated by
1.9.3