Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8f84a5a

Browse files
jcolemanCommitfest Bot
authored and
Commitfest Bot
committed
Recurse weak and strong implication at the same time
This is particularly useful for implication as used in refutation proofs with "NOT x" clauses. We don't plumb through external callers this way since they are generally interested in one or the other.
1 parent 5da2597 commit 8f84a5a

File tree

1 file changed

+51
-46
lines changed

1 file changed

+51
-46
lines changed

src/backend/optimizer/util/predtest.c

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,12 @@ typedef struct PredIterInfoData
7979
(info).cleanup_fn(&(info)); \
8080
} while (0)
8181

82+
typedef int ImplicationType;
83+
#define STRONG ((ImplicationType) 0x01)
84+
#define WEAK ((ImplicationType) 0x02)
8285

8386
static bool predicate_implied_by_recurse(Node *clause, Node *predicate,
84-
bool weak);
87+
ImplicationType implication_mask);
8588
static bool predicate_refuted_by_recurse(Node *clause, Node *predicate,
8689
bool weak);
8790
static PredClass predicate_classify(Node *clause, PredIterInfo info);
@@ -96,11 +99,11 @@ static void arrayexpr_startup_fn(Node *clause, PredIterInfo info);
9699
static Node *arrayexpr_next_fn(PredIterInfo info);
97100
static void arrayexpr_cleanup_fn(PredIterInfo info);
98101
static bool predicate_implied_by_simple_clause(Expr *predicate, Node *clause,
99-
bool weak);
102+
ImplicationType implication_mask);
100103
static bool predicate_refuted_by_simple_clause(Expr *predicate, Node *clause,
101104
bool weak);
102105
static bool predicate_implied_not_null_by_clause(Expr *predicate, Node *clause,
103-
bool weak);
106+
ImplicationType implication_mask);
104107
static Node *extract_not_arg(Node *clause);
105108
static Node *extract_strong_not_arg(Node *clause);
106109
static bool clause_is_strict_for(Node *clause, Node *subexpr, bool allow_false);
@@ -178,7 +181,7 @@ predicate_implied_by(List *predicate_list, List *clause_list,
178181
c = (Node *) clause_list;
179182

180183
/* And away we go ... */
181-
return predicate_implied_by_recurse(c, p, weak);
184+
return predicate_implied_by_recurse(c, p, weak ? WEAK : STRONG);
182185
}
183186

184187
/*
@@ -295,7 +298,7 @@ predicate_refuted_by(List *predicate_list, List *clause_list,
295298
*/
296299
static bool
297300
predicate_implied_by_recurse(Node *clause, Node *predicate,
298-
bool weak)
301+
ImplicationType implication_mask)
299302
{
300303
PredIterInfoData clause_info;
301304
PredIterInfoData pred_info;
@@ -323,7 +326,7 @@ predicate_implied_by_recurse(Node *clause, Node *predicate,
323326
iterate_begin(pitem, predicate, pred_info)
324327
{
325328
if (!predicate_implied_by_recurse(clause, pitem,
326-
weak))
329+
implication_mask))
327330
{
328331
result = false;
329332
break;
@@ -343,7 +346,7 @@ predicate_implied_by_recurse(Node *clause, Node *predicate,
343346
iterate_begin(pitem, predicate, pred_info)
344347
{
345348
if (predicate_implied_by_recurse(clause, pitem,
346-
weak))
349+
implication_mask))
347350
{
348351
result = true;
349352
break;
@@ -361,7 +364,7 @@ predicate_implied_by_recurse(Node *clause, Node *predicate,
361364
iterate_begin(citem, clause, clause_info)
362365
{
363366
if (predicate_implied_by_recurse(citem, predicate,
364-
weak))
367+
implication_mask))
365368
{
366369
result = true;
367370
break;
@@ -379,7 +382,7 @@ predicate_implied_by_recurse(Node *clause, Node *predicate,
379382
iterate_begin(citem, clause, clause_info)
380383
{
381384
if (predicate_implied_by_recurse(citem, predicate,
382-
weak))
385+
implication_mask))
383386
{
384387
result = true;
385388
break;
@@ -407,7 +410,7 @@ predicate_implied_by_recurse(Node *clause, Node *predicate,
407410
iterate_begin(pitem, predicate, pred_info)
408411
{
409412
if (predicate_implied_by_recurse(citem, pitem,
410-
weak))
413+
implication_mask))
411414
{
412415
presult = true;
413416
break;
@@ -435,7 +438,7 @@ predicate_implied_by_recurse(Node *clause, Node *predicate,
435438
iterate_begin(citem, clause, clause_info)
436439
{
437440
if (!predicate_implied_by_recurse(citem, predicate,
438-
weak))
441+
implication_mask))
439442
{
440443
result = false;
441444
break;
@@ -458,7 +461,7 @@ predicate_implied_by_recurse(Node *clause, Node *predicate,
458461
iterate_begin(pitem, predicate, pred_info)
459462
{
460463
if (!predicate_implied_by_recurse(clause, pitem,
461-
weak))
464+
implication_mask))
462465
{
463466
result = false;
464467
break;
@@ -476,7 +479,7 @@ predicate_implied_by_recurse(Node *clause, Node *predicate,
476479
iterate_begin(pitem, predicate, pred_info)
477480
{
478481
if (predicate_implied_by_recurse(clause, pitem,
479-
weak))
482+
implication_mask))
480483
{
481484
result = true;
482485
break;
@@ -493,7 +496,7 @@ predicate_implied_by_recurse(Node *clause, Node *predicate,
493496
return
494497
predicate_implied_by_simple_clause((Expr *) predicate,
495498
clause,
496-
weak);
499+
implication_mask);
497500
}
498501
break;
499502
}
@@ -627,7 +630,7 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate,
627630
not_arg = extract_not_arg(predicate);
628631
if (not_arg &&
629632
predicate_implied_by_recurse(clause, not_arg,
630-
false))
633+
STRONG))
631634
return true;
632635

633636
/*
@@ -709,7 +712,7 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate,
709712
not_arg = extract_not_arg(predicate);
710713
if (not_arg &&
711714
predicate_implied_by_recurse(clause, not_arg,
712-
false))
715+
STRONG))
713716
return true;
714717

715718
/*
@@ -736,26 +739,24 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate,
736739
* If A is a strong NOT-clause, A R=> B if B => A's arg
737740
*
738741
* Since A is strong, we may assume A's arg is false (not just
739-
* not-true). If B weakly implies A's arg, then B can be neither
740-
* true nor null, so that strong refutation is proven. If B
741-
* strongly implies A's arg, then B cannot be true, so that weak
742-
* refutation is proven.
742+
* not-true). If B strongly implies A's arg, then B cannot be true,
743+
* so that weak refutation is proven. If B weakly implies A's arg,
744+
* then B can be neither true nor null, so that strong refutation
745+
* are proven. In that case we can also prove weak refutation since
746+
* if B must be false, then surely it is not true.
743747
*/
744748
not_arg = extract_strong_not_arg(clause);
745-
if (not_arg &&
746-
predicate_implied_by_recurse(predicate, not_arg,
747-
!weak))
748-
return true;
749+
if (not_arg)
750+
{
751+
int useful_implications = weak ? STRONG : WEAK;
749752

750-
/*
751-
* Because weak refutation expands the allowed outcomes for B
752-
* from "false" to "false or null", we can additionally prove
753-
* weak refutation in the case that strong refutation is proven.
754-
*/
755-
if (weak && not_arg &&
756-
predicate_implied_by_recurse(predicate, not_arg,
757-
true))
758-
return true;
753+
if (weak)
754+
useful_implications |= WEAK;
755+
756+
if (predicate_implied_by_recurse(predicate, not_arg,
757+
useful_implications))
758+
return true;
759+
}
759760

760761
switch (pclass)
761762
{
@@ -805,7 +806,7 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate,
805806
not_arg = extract_not_arg(predicate);
806807
if (not_arg &&
807808
predicate_implied_by_recurse(clause, not_arg,
808-
false))
809+
STRONG))
809810
return true;
810811

811812
/*
@@ -1113,8 +1114,12 @@ arrayexpr_cleanup_fn(PredIterInfo info)
11131114
*/
11141115
static bool
11151116
predicate_implied_by_simple_clause(Expr *predicate, Node *clause,
1116-
bool weak)
1117+
ImplicationType implication_mask)
11171118
{
1119+
bool weak = implication_mask & WEAK;
1120+
bool strong = implication_mask & STRONG;
1121+
1122+
11181123
/* Allow interrupting long proof attempts */
11191124
CHECK_FOR_INTERRUPTS();
11201125

@@ -1302,7 +1307,7 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause,
13021307
* must be not null.
13031308
*/
13041309
if (predicate_implied_not_null_by_clause(predntest->arg,
1305-
clause, weak))
1310+
clause, implication_mask))
13061311
return true;
13071312
break;
13081313
case IS_NULL:
@@ -1332,7 +1337,7 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause,
13321337
* We can only prove strong implication here since
13331338
* "null is true" is false rather than null.
13341339
*/
1335-
if (!weak && equal(clause, predbtest->arg))
1340+
if (strong && equal(clause, predbtest->arg))
13361341
return true;
13371342
break;
13381343
case IS_FALSE:
@@ -1342,7 +1347,7 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause,
13421347
* We can only prove strong implication here since "not
13431348
* null" is null rather than true.
13441349
*/
1345-
if (!weak && is_notclause(clause) &&
1350+
if (strong && is_notclause(clause) &&
13461351
equal(get_notclausearg(clause), predbtest->arg))
13471352
return true;
13481353
break;
@@ -1401,7 +1406,7 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause,
14011406
*
14021407
* For example: truth of x implies x is not unknown.
14031408
*/
1404-
if (predicate_implied_not_null_by_clause(predbtest->arg, clause, weak))
1409+
if (predicate_implied_not_null_by_clause(predbtest->arg, clause, implication_mask))
14051410
return true;
14061411
break;
14071412
}
@@ -1444,7 +1449,7 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause,
14441449
* cycles on at this point.
14451450
*/
14461451
static bool
1447-
predicate_implied_not_null_by_clause(Expr *predicate, Node *clause, bool weak)
1452+
predicate_implied_not_null_by_clause(Expr *predicate, Node *clause, ImplicationType implication_mask)
14481453
{
14491454
switch (nodeTag(clause))
14501455
{
@@ -1517,7 +1522,7 @@ predicate_implied_not_null_by_clause(Expr *predicate, Node *clause, bool weak)
15171522
* work for weak implication, though, since the clause yielding the
15181523
* non-false value NULL means the predicate will evaluate to false.
15191524
*/
1520-
if (!weak && clause_is_strict_for(clause, (Node *) predicate, true))
1525+
if (implication_mask & STRONG && clause_is_strict_for(clause, (Node *) predicate, true))
15211526
return true;
15221527

15231528
return false;
@@ -1578,7 +1583,7 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause,
15781583
* = false" would mean both our clause and our
15791584
* predicate would evaluate to "false".
15801585
*/
1581-
if (predicate_implied_not_null_by_clause(clausentest->arg, (Node *) predicate, true))
1586+
if (predicate_implied_not_null_by_clause(clausentest->arg, (Node *) predicate, WEAK))
15821587
return true;
15831588

15841589
/*
@@ -1588,7 +1593,7 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause,
15881593
* in the predicate, it's known immutable).
15891594
*/
15901595
if (weak &&
1591-
clause_is_strict_for((Node *) predicate, (Node *) clausentest->arg, true))
1596+
clause_is_strict_for((Node *) predicate, (Node *) clausentest->arg, WEAK))
15921597
return true;
15931598

15941599
return false; /* we can't succeed below... */
@@ -1665,7 +1670,7 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause,
16651670
* = false" would mean both our clause and our
16661671
* predicate would evaluate to "false".
16671672
*/
1668-
if (predicate_implied_not_null_by_clause(clausebtest->arg, (Node *) predicate, true))
1673+
if (predicate_implied_not_null_by_clause(clausebtest->arg, (Node *) predicate, WEAK))
16691674
return true;
16701675

16711676
/*
@@ -1728,7 +1733,7 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause,
17281733
* refutation is a strict superset of weak
17291734
* refutation.
17301735
*/
1731-
if (predicate_implied_not_null_by_clause(predntest->arg, clause, false))
1736+
if (predicate_implied_not_null_by_clause(predntest->arg, clause, STRONG))
17321737
return true;
17331738
}
17341739
break;
@@ -1759,7 +1764,7 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause,
17591764
* refutation is a strict superset of weak
17601765
* refutation.
17611766
*/
1762-
if (predicate_implied_not_null_by_clause(predbtest->arg, clause, false))
1767+
if (predicate_implied_not_null_by_clause(predbtest->arg, clause, STRONG))
17631768
return true;
17641769

17651770
return false; /* we can't succeed below... */

0 commit comments

Comments
 (0)