Skip to content

Commit b883378

Browse files
committed
Large changes to negation code
1. Change in naming 2. Multiple guesses at once 3. Distinction between delaying and committing to a condition Note: This commit does not change the rules yet
1 parent d6df61d commit b883378

File tree

3 files changed

+89
-38
lines changed

3 files changed

+89
-38
lines changed

share/prolog/oorules/guess.pl

+54-21
Original file line numberDiff line numberDiff line change
@@ -1667,38 +1667,71 @@
16671667
negation_helper(not(factNOTRealDestructor(RealDestructor))),
16681668
true.
16691669

1670-
tryNegation(G) :-
1671-
loginfoln('Guessing ~Q.', negation_commit(G)),
1672-
try_assert(negation_commit(G)).
1670+
tryDelay((G,P,Commit)) :-
1671+
try_retract(delay_queue(G, P, Commit)),
16731672

1674-
tryNOTNegation(G) :-
1675-
loginfoln('Guessing ~Q.', negation_fail(G)),
1676-
try_assert(negation_fail(G)).
1673+
% Do nothing if we've already committed one way or the other
1674+
%% (not(G) -> true;
1675+
%% delay_goal(G, _) -> true;
1676+
%% delay_fail(G) -> true;
1677+
1678+
loginfoln('Guessing ~Q.', delay_goal(G, Commit)),
1679+
try_assert(delay_goal(G, Commit))).
1680+
1681+
tryNOTDelay((G,P)) :-
1682+
loginfoln('tryNOTDelay'),
1683+
try_retract(delay_queue(G, P, Commit)),
1684+
1685+
% Do nothing if we've already committed one way or the other
1686+
%% (not(G) -> true;
1687+
%% delay_goal(G, _) -> true;
1688+
%% delay_fail(G) -> true;
1689+
1690+
loginfoln('Guessing ~Q.', delay_fail(G)),
1691+
try_assert(delay_fail(G))).
1692+
1693+
tryOrNOTDelay((G, P)) :-
1694+
% XXX Optimization for not(G)...
1695+
1696+
try_retract(delay_queue(G, P)),
1697+
1698+
% Do nothing if we've already committed one way or the other
1699+
delay_goal(G, _) -> true;
1700+
delay_fail(G) -> true;
16771701

1678-
tryOrNOTNegation(G) :-
1679-
%likelyDeletingDestructor(Method, _RealDestructor),
1680-
doNotGuessHelper(negation_commit(G),
1681-
negation_fail(G)),
16821702
(
1683-
tryNegation(G);
1684-
tryNOTNegation(G);
1685-
logwarnln('Something is wrong upstream: ~Q.', negation(Method)),
1703+
tryDelay(G);
1704+
tryNOTDelay(G);
1705+
logwarnln('Something is wrong upstream: ~Q.', delay(Method)),
16861706
fail
16871707
).
16881708

1689-
guessNegation(Out) :-
1690-
reportFirstSeen('guessNegation'),
1709+
guessDelay(Out) :-
1710+
reportFirstSeen('guessDelay'),
1711+
1712+
% Remove each false or already committed to delay
1713+
forall(delay_queue(G, P, Commit),
1714+
((not(G);
1715+
delay_goal(G, _);
1716+
delay_fail(G))
1717+
-> (logdebugln('Removing outdated delay goal ~Q', [G]),
1718+
retract(delay_queue(G, P, Commit)))
1719+
; true)),
1720+
1721+
!,
16911722

1692-
%setof(P, negation_queue(_, P), Pset),
1693-
%max_list(Pset, Pmax),
1723+
setof(P, delay_queue(_, P, _), Pset),
1724+
max_list(Pset, Pmax),
16941725

16951726
% Sorting the queue takes a while. We should really use a priority queue...
16961727
% but this hack works ok for now.
1697-
member(Pmax, [0, -10, _]),
1728+
%member(Pmax, [0, -10, _]),
16981729

1699-
retract(negation_queue(G, Pmax)),
1700-
!,
1701-
(G, not(negation_commit(G)), not(negation_fail(G)) -> Out = tryOrNOTNegation(G); guessNegation(Out)).
1730+
setof((G, Pmax, Commit),
1731+
delay_queue(G, Pmax, Commit),
1732+
Gset),
1733+
1734+
Out = tryBinarySearch(tryDelay, tryNOTDelay, Gset).
17021735

17031736
%% Local Variables:
17041737
%% mode: prolog

share/prolog/oorules/insanity.pl

+1-1
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@
332332
% that way.
333333
:- table insanityNegation/1 as incremental.
334334
insanityNegation(Out) :-
335-
negation_commit(G),
335+
delay_goal(G, true),
336336

337337
not(G),
338338

share/prolog/oorules/util.pl

+34-16
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,54 @@
55

66
:- use_module(library(lists), [append/3, nth1/4, list_to_set/2]).
77

8-
:- dynamic negation_queue/2.
9-
:- dynamic negation_fail/1.
10-
:- dynamic negation_commit/1 as incremental.
8+
% Delayed and committed negations. The following code is used to indicate a delayed check,
9+
% which is how it sounds. A delayed check may optionally be committed to, which ensures that
10+
% the check can not become false in the future.
1111

12-
negation_helper(G) :- negation_helper(G, 0).
12+
:- dynamic delay_queue/3.
1313

14-
negation_helper(G, _) :-
15-
var(G) -> throw_with_backtrace(user_error(negation_helper)).
14+
:- dynamic delay_fail/1.
1615

17-
% We've already committed to G
18-
negation_helper(G, _) :-
19-
negation_commit(G),
20-
logtraceln('Already committed ~Q', G),
16+
%:- dynamic delay_commit/1 as incremental.
17+
18+
% delayed_goal(Goal, Commit). Commit=true iff the goal should never become false in the
19+
% future.
20+
:- dynamic delay_goal/2 as incremental.
21+
22+
%delay_helper(G) :- delay_helper(G, 0, false).
23+
24+
delay(G) :- delay_helper(G, 0, false).
25+
26+
delay_and_commit(G) :- delay_and_commit(G, 0).
27+
28+
delay_and_commit(G, P) :- delay_helper(G, P, true).
29+
30+
delay_helper(G, _, _) :-
31+
var(G) -> throw_with_backtrace(user_error(delay_helper)).
32+
33+
% We've already delayed for G
34+
delay_helper(G, _, _) :-
35+
delay_goal(G, _),
36+
logtraceln('Already delayed ~Q', G),
2137
!.
2238

2339
% G results in a sanity failure
24-
negation_helper(G, _) :-
25-
negation_fail(G), !, fail.
40+
delay_helper(G, _, _) :-
41+
delay_fail(G), !, fail.
2642

2743
% G isn't true right now.
28-
negation_helper(G, _) :-
44+
delay_helper(G, _, _) :-
2945
not(G), !, fail.
3046

3147
% Queue G and fail.
32-
negation_helper(G, P) :-
48+
delay_helper(G, P, Commit) :-
3349
!,
34-
(negation_queue(G, OldP), P >= OldP)
50+
(delay_queue(G, OldP, Commit), P >= OldP)
3551
% There is a better or same priority queued element
3652
-> fail
37-
; logdebugln('I am queueing negation ~Q', G), assert(negation_queue(G, P)), logdebugln('done'), fail.
53+
; logdebugln('I am queueing delay ~Q', G),
54+
assert(delay_queue(G, P, Commit)),
55+
fail.
3856

3957

4058
sort_tuple((A,B), (C,D)) :-

0 commit comments

Comments
 (0)