1:- module(pure,
2 [ is_pure_pred/1,
3 is_pure_pred/2,
4 is_pure_clause/1,
5 is_pure_body/1,
6 is_pure_body/2,
7 is_impure/1
8 ]). 9
10:- use_module(library(lists)). 11:- use_module(library(resolve_calln)). 12:- use_module(library(qualify_meta_goal)). 13
14:- meta_predicate
15 is_impure(0 ),
16 is_pure_pred(0 ),
17 is_pure_pred(0, 1 ),
18 is_pure_pred(0, 1, +),
19 is_pure_body(0 ),
20 is_pure_body(0, 1 ). 21
22is_impure(_:(\+ _)) :- !, fail.
23is_impure(M:Head) :- \+ predicate_property(M:Head, interpreted).
24
25is_pure_pred(Head) :-
26 is_pure_pred(Head, is_impure, []).
37is_pure_pred(Head, IsImpure) :-
38 is_pure_pred(Head, IsImpure, []).
45is_pure_clause(Ref) :-
46 is_pure_clause(Ref, is_impure, []).
47
48is_pure_pred(M:Head, IsImpure, Stack1) :-
49 \+ call(IsImpure, M:Head),
50 findall(Ref, ( catch(clause(M:Head, _, Ref), _, fail),
51 \+ memberchk(Ref, Stack1)
52 ), RefL),
53 append(RefL, Stack1, Stack),
54 forall(member(Ref, RefL),
55 is_pure_clause(Ref, IsImpure, Stack)).
56
57is_pure_clause(Ref, IsImpure, Stack) :-
58 clause_property(Ref, module(CM)),
59 catch(clause(M:Head, Body, Ref), _, fail),
60 61 M:Head \== CM:Body,
62 M:call(Head) \== CM:Body,
63 is_pure_body(Body, CM, IsImpure, Stack).
64
69
72
73is_pure_body(M:G) :-
74 is_pure_body(G, M, is_impure, []).
75
76is_pure_body(M:G, IsImpure) :-
77 is_pure_body(G, M, IsImpure, []).
78
79is_pure_body(G, M, IsImpure, _) :-
80 var(G),
81 !,
82 freeze(G, is_pure_pred(M:G, IsImpure)).
83is_pure_body(true, _, _, _) :- !.
84is_pure_body(fail, _, _, _) :- !.
85is_pure_body(_=_, _, _, _) :- !.
86is_pure_body(\+ _, _, _, _) :- !, fail.
87is_pure_body(@(G, CM), _, IsImpure, Stack) :-
88 !,
89 strip_module(CM:G, M, H),
90 is_pure_body_mod(H, M, CM, IsImpure, Stack).
91is_pure_body(M:G, _, IsImpure, Stack) :-
92 !,
93 is_pure_body_mod(G, M, M, IsImpure, Stack).
94is_pure_body((A,B), M, IsImpure, Stack) :-
95 !,
96 is_pure_body(A, M, IsImpure, Stack),
97 is_pure_body(B, M, IsImpure, Stack).
98is_pure_body((A;B), M, IsImpure, Stack) :-
99 !,
100 is_pure_body(A, M, IsImpure, Stack),
101 is_pure_body(B, M, IsImpure, Stack).
102is_pure_body(CallN, M, IsImpure, Stack) :-
103 do_resolve_calln(CallN, Call),
104 is_pure_body(Call, M, IsImpure, Stack).
105is_pure_body(phrase(DCG, L, T), M, IsImpure, Stack) :-
106 !,
107 dcg_translate_rule(('$head$' --> DCG, '$sink$'), _, ('$head$'(L, _) :- Lits, '$sink$'(T, _)), _),
108 is_pure_body(Lits, M, IsImpure, Stack).
109is_pure_body(phrase(DCG, L), M, IsImpure, Stack) :-
110 !,
111 is_pure_body(phrase(DCG, L, []), M, IsImpure, Stack).
112is_pure_body(H, M, IsImpure, Stack) :-
113 ( predicate_property(M:H, meta_predicate(Meta))
114 ->qualify_meta_goal(M:H, Meta, Goal)
115 ; Goal = H
116 ),
117 is_pure_pred(M:Goal, IsImpure, Stack).
118
132
133is_pure_body_mod(H, M, _, IsImpure, Stack) :-
134 is_pure_body(H, M, IsImpure, Stack)