-
Notifications
You must be signed in to change notification settings - Fork 131
Expand file tree
/
Copy pathnon-ors.cc
More file actions
143 lines (135 loc) · 6.6 KB
/
non-ors.cc
File metadata and controls
143 lines (135 loc) · 6.6 KB
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
/*****************************************************************************
* \file non-ors.cc *
* *
* Description: Contains the matchNonORs() functions for the EntList descen- *
* dants. matchNonORs() functions loop through the EntList *
* children of this whose JoinType != OR (and check a Simple- *
* List itself) to determine how well they match an EntNode. *
* *
* Created by: David Rosenfeld *
* Date: 10/17/96 *
*****************************************************************************/
#include "clstepcore/complexSupport.h"
/**
* Checks if we match the nodes of ents. If only one unmarked is left
* and we match it, return MATCHALL. More likely, we'll return one of the
* other return values. (See descript of MatchType values in complex-
* Support.h.)
*/
MatchType SimpleList::matchNonORs( EntNode * ents ) {
EntNode * eptr = ents;
int comp;
while( eptr != NULL ) {
if( ( comp = strcmp( name, eptr->name ) ) == 0 ) {
if( ! eptr->marked( MARK ) ) {
// NOTE - this cond also returns true if eptr did have an OR-
// MARK. We don't want to remark now (since we're also trying
// out OR choices -- we know this because no OR's are done
// until after all the non-OR's). But, we do want to return
// MATCHSOME, as below. Since The prev OR which marked this
// may one time later try another path, we want to record that
// our OR can also mark it. So we return MATCHSOME saying
// this is a viable option we may one time want to try.
if( eptr->mark == NOMARK ) {
eptr->setmark();
I_marked = MARK;
// Remember that we're the one who marked this. (Nec. in
// case we have to unmark later to try out another OR
// branch.)
if( ents->allMarked() ) {
// If this was the only unmarked left,
viable = MATCHALL;
return MATCHALL;
}
}
viable = MATCHSOME;
return MATCHSOME;
}
viable = SATISFIED;
return SATISFIED;
// Couldn't mark any more, but at least we're not placing a re-
// quirement ents couldn't meet.
}
if( comp < 0 ) {
// We're beyond name in the ents list. No more checking to do.
break;
}
eptr = eptr->next;
}
// At this point, we went through the list without finding a match. Result
// = UNSATISFIED - no match.
viable = UNSATISFIED;
return UNSATISFIED;
}
/**
* Loop through the children of this matching as many of the nodes of ents
* as we can. We skip all OrList descendants. Those are processed later
* only after all the non-conditional descendants, so that when we start
* processing them we'll be able to tell which OR choices are viable, and
* which are unnec.
*/
MatchType AndOrList::matchNonORs( EntNode * ents ) {
EntList * child = childList->firstNot( OR );
MatchType retval;
while( child != NULL ) {
if( ( retval = child->matchNonORs( ents ) ) == MATCHALL ) {
if( prevKnown( child ) ) {
viable = MATCHALL;
return MATCHALL;
// We found a good solution. Nothing else to do. (Some higher
// AND may have some other req's ents can't meet, but that's
// not our problem. If that happens, AND will return UNSATIS-
// FIED, or an even higher OR will undo all and will try
// another path.)
// The prevKnown() fn is used to check that we haven't come
// across any UNKNOWNs yet. If we have, we can't be sure the
// MATCHALL is valid. An illustration: One of our previous
// children was an AND who had a SIMPLE child and an OR child.
// The SIMPLE child matched one EntNode. The OR child is
// UNKNOWN, since we haven't matchOR()'ed yet. Possibly, our
// retval of MATCHALL is in part due to the SIMPLE child of
// the AND. But if the OR child of the AND returns UNSAT when
// we run matchOR(), we'll unmark the SIMPLE child too. Thus,
// we can only be sure of a MATCHALL if nothing is UNKNOWN.
// (Note that future UNKNOWN children don't bother us (in fact
// all future children are UNKNOWN by default since they have
// not been touched). This is because we're an ANDOR and can
// skip them altogether. But previous children we have visi-
// ted already, and we can't ignore, as above. Compare to
// AndOrList::matchORs(), where since all children had been
// visited already in matchNonORs(), we were not able to stop
// in process as here at all.)
}
} else if( retval == UNSATISFIED ) {
// Unmark whatever we may have marked. (E.g., there may have
// been an AND beneath and it started marking and then found one
// it couldn't match.)
child->unmarkAll( ents );
}
child = child->nextNot( OR );
}
setViableVal( ents );
return viable;
}
/**
* Checks if the AndList contains the set of nodes in ents. Skip OrList
* descendants.
*/
MatchType AndList::matchNonORs( EntNode * ents ) {
EntList * child = childList->firstNot( OR );
while( child != NULL ) {
if( child->matchNonORs( ents ) == UNSATISFIED ) {
viable = UNSATISFIED;
return UNSATISFIED;
// This means the whole AndList has failed, by definition.
}
child = child->nextNot( OR );
// Note - we loop through all even if one of our children returned
// MATCHALL. Since we're an AND, we must look through all branches -
// to search for any other conditions we can't meet. If one of our
// children did MATCHALL, its viable val will be set to MATCHALL and
// we'll catch it in setViableVal() called below.
}
setViableVal( ents );
return viable;
}