Completed
Push — master ( 17dff3...f2d821 )
by mw
42:32 queued 07:38
created

Conjunction::addDescription()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 13
nc 6
nop 1
dl 0
loc 25
ccs 13
cts 13
cp 1
crap 5
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
namespace SMW\Query\Language;
4
5
/**
6
 * Description of a collection of many descriptions, all of which
7
 * must be satisfied (AND, conjunction).
8
 *
9
 * Corresponds to conjunction in OWL and SPARQL. Not available in RDFS.
10
 *
11
 * @license GNU GPL v2+
12
 * @since 1.6
13
 *
14
 * @author Markus Krötzsch
15
 */
16
class Conjunction extends Description {
17
18
	/**
19
	 * @var Description[]
20
	 */
21
	protected $descriptions = array();
22
23
	/**
24
	 * @since 1.6
25
	 *
26
	 * @param array $descriptions
27
	 */
28 84
	public function __construct( array $descriptions = array() ) {
29 84
		foreach ( $descriptions as $description ) {
30 82
			$this->addDescription( $description );
31
		}
32 84
	}
33
34
	/**
35
	 * @see Description::getFingerprint
36
	 * @since 2.5
37
	 *
38
	 * @return string
39
	 */
40 83
	public function getFingerprint() {
41
42 83
		if ( $this->fingerprint !== null ) {
43 78
			return $this->fingerprint;
44
		}
45
46 83
		$fingerprint = array();
47
48
		// Filter equal signatures
49 83
		foreach ( $this->descriptions as $description ) {
50 83
			$fingerprint[$description->getFingerprint()] = true;
51
		}
52
53
		// Sorting to generate a constant fingerprint independent of its
54
		// position within a conjunction ( [Foo]][[Bar]], [[Bar]][[Foo]])
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
55 83
		ksort( $fingerprint );
56
57 83
		return $this->fingerprint = 'C:' . md5( implode( '|', array_keys( $fingerprint ) ) );
58
	}
59
60 79
	public function getDescriptions() {
61 79
		return $this->descriptions;
62
	}
63
64 83
	public function addDescription( Description $description ) {
65
66 83
		$this->fingerprint = null;
67
68 83
		if ( ! ( $description instanceof ThingDescription ) ) {
69 83
			if ( $description instanceof Conjunction ) { // absorb sub-conjunctions
70 4
				foreach ( $description->getDescriptions() as $subdesc ) {
71 4
					$this->descriptions[$subdesc->getFingerprint()] = $subdesc;
72
				}
73
			} else {
74 83
				$this->descriptions[$description->getFingerprint()] = $description;
75
			}
76
77
			// move print descriptions downwards
78
			///TODO: This may not be a good solution, since it does modify $description and since it does not react to future changes
79 83
			$this->m_printreqs = array_merge( $this->m_printreqs, $description->getPrintRequests() );
80 83
			$description->setPrintRequests( array() );
81
		}
82
83 83
		$fingerprint = $this->getFingerprint();
84
85 83
		foreach ( $this->descriptions as $description ) {
86 83
			$description->setMembership( $fingerprint );
87
		}
88 83
	}
89
90 32
	public function getQueryString( $asvalue = false ) {
91 32
		$result = '';
92
93 32
		foreach ( $this->descriptions as $desc ) {
94 32
			$result .= ( $result ? ' ' : '' ) . $desc->getQueryString( false );
95
		}
96
97 32
		if ( $result === '' ) {
98
			return $asvalue ? '+' : '';
99
		}
100
101
		// <q> not needed for stand-alone conjunctions (AND binds stronger than OR)
102 32
		return $asvalue ? " <q>{$result}</q> " : $result;
103
	}
104
105 2
	public function isSingleton() {
106 2
		foreach ( $this->descriptions as $d ) {
107 2
			if ( $d->isSingleton() ) {
108 2
				return true;
109
			}
110
		}
111 1
		return false;
112
	}
113
114 26
	public function getSize() {
115 26
		$size = 0;
116
117 26
		foreach ( $this->descriptions as $desc ) {
118 26
			$size += $desc->getSize();
119
		}
120
121 26
		return $size;
122
	}
123
124 26
	public function getDepth() {
125 26
		$depth = 0;
126
127 26
		foreach ( $this->descriptions as $desc ) {
128 26
			$depth = max( $depth, $desc->getDepth() );
129
		}
130
131 26
		return $depth;
132
	}
133
134 4
	public function getQueryFeatures() {
135 4
		$result = SMW_CONJUNCTION_QUERY;
136
137 4
		foreach ( $this->descriptions as $desc ) {
138 4
			$result = $result | $desc->getQueryFeatures();
139
		}
140
141 4
		return $result;
142
	}
143
144 73
	public function prune( &$maxsize, &$maxdepth, &$log ) {
145 73
		if ( $maxsize <= 0 ) {
146 1
			$log[] = $this->getQueryString();
147 1
			return new ThingDescription();
148
		}
149
150 73
		$prunelog = array();
151 73
		$newdepth = $maxdepth;
152 73
		$result = new Conjunction();
153
154 73
		foreach ( $this->descriptions as $desc ) {
155 73
			$restdepth = $maxdepth;
156 73
			$result->addDescription( $desc->prune( $maxsize, $restdepth, $prunelog ) );
157 73
			$newdepth = min( $newdepth, $restdepth );
158
		}
159
160 73
		if ( count( $result->getDescriptions() ) > 0 ) {
161 73
			$log = array_merge( $log, $prunelog );
162 73
			$maxdepth = $newdepth;
163
164 73
			if ( count( $result->getDescriptions() ) == 1 ) { // simplify unary conjunctions!
165 3
				$descriptions = $result->getDescriptions();
166 3
				$result = array_shift( $descriptions );
167
			}
168
169 73
			$result->setPrintRequests( $this->getPrintRequests() );
170
171 73
			return $result;
172
		} else {
173
			$log[] = $this->getQueryString();
174
175
			$result = new ThingDescription();
176
			$result->setPrintRequests( $this->getPrintRequests() );
177
178
			return $result;
179
		}
180
	}
181
182
}
183