It was the 19th of August, a quiet Thursday evening in the sleepy Halberd town. The Town Library walls stood tall and the dim pool of lamplight towered over the reading tables. All of a sudden, the silence was broken—not by a whisper, but by murder. Professor Harold Finch, a respected yet abrasive academic, was found dead in the reading room of the town library at 8:00 PM. He’d been struck down with a heavy brass bookend. His glasses lay shattered. The walls, lined with books, seemed to hold their breath. It looked like a brutal, deliberate strike!
Detective Monroe was called in, and it didn’t take long to realize that everyone present had something to hide. There were five people in the building at the time. Clara claimed she had been sorting books in the lobby. Mark, the janitor, insisted he’d been cleaning the second-floor bathrooms. But the access logs showed he’d never gone up. Elena, a history student and once-close protégé of Finch, admitted to a recent falling-out with him over a failed thesis review and said she’d seen Clara in the reading room around 7:40 PM. Tom, the archivist, was working in the basement. He had no alibi, and his unlocked door violated protocol. Rita, the security officer, claimed she was on patrol and had seen Mark in the basement at 7:50 PM. But Mark denied ever being there.
The evidence was messy. A bloody glove with Mark’s fingerprints was found in a trash can in the basement, but the murder weapon that was retrieved from the history section had a partial print that didn’t belong to him. It belonged to Clara. Even more strange findings: the CCTV footage had been deleted from the hour before the murder, and only someone with security clearance could have done that. That someone was Rita, who was also missing from the camera feeds for a suspicious 20-minute window.
The story began to unfold as Detective Monroe laid out all the important pieces in a knowledge graph, and modeled suspects, clues, evidence and motives.
He then wrote a Cypher query to find the real culprit. It was difficult to decipher because of all the contradictions. So, he assigned weights to various clues and evidence.
Clue Type | Weight |
Fingerprint on Murder Weapon | 4 |
At Crime Scene at Right Time | 3 |
Motive (argument or grudge) | 2.5 |
Tampering Evidence (e.g. CCTV) | 2.5 |
Blood evidence (glove) | 2 |
Proof of being at claimed location | 2 |
Relation to Guilty Party | 1 |
MATCH (v:Victim)-[:FOUND_DEAD_IN]->(p:Place)
MATCH (s:Suspect)
OPTIONAL MATCH (s)-[:FINGERPRINT_FOUND_ON]->(weapon:Evidence {isWeapon: true})
OPTIONAL MATCH (s)-[:FINGERPRINT_FOUND_ON]->(glove:Evidence {name: 'Bloody Glove'})
OPTIONAL MATCH (s)-[argued:ARGUED_WITH]->(v:Victim)
OPTIONAL MATCH (s)-[delcctv:DELETED]->(:Evidence {name: 'CCTV Footage'})
OPTIONAL MATCH (s)-[seenloc:SEEN_LOCATION]->(p)
OPTIONAL MATCH (s)-[rel:SISTER_OF]->(:Suspect {name: 'Clara'})
OPTIONAL MATCH (s)-[noalibi:HAS_NO]->(:Clue {name: 'Alibi'})
WITH
s.name AS suspect, v.name as victim, p.name AS crimeScene,
COUNT(DISTINCT weapon)*4 AS weaponScore,
COUNT(DISTINCT seenloc)*3 AS atCrimeSceneScore,
COUNT(DISTINCT argued)*2.5 AS motiveScore,
COUNT(DISTINCT delcctv)*2.5 AS tamperScore,
COUNT(DISTINCT glove)*2 AS gloveScore,
COUNT(DISTINCT noalibi)*2 AS noAlibiScore,
COUNT(DISTINCT rel)*1 AS relationScore
WITH suspect,
weaponScore + atCrimeSceneScore + motiveScore + tamperScore + gloveScore + noAlibiScore + relationScore AS totalSuspicion
ORDER BY totalSuspicion DESC
RETURN suspect AS LikelyCulprit, totalSuspicion
MATCH (s:Suspect)
OPTIONAL MATCH (s)-[:FINGERPRINT_FOUND_ON]->(weapon:Evidence {isWeapon: true})
OPTIONAL MATCH (s)-[:FINGERPRINT_FOUND_ON]->(glove:Evidence {name: 'Bloody Glove'})
OPTIONAL MATCH (s)-[argued:ARGUED_WITH]->(v:Victim)
OPTIONAL MATCH (s)-[delcctv:DELETED]->(:Evidence {name: 'CCTV Footage'})
OPTIONAL MATCH (s)-[seenloc:SEEN_LOCATION]->(p)
OPTIONAL MATCH (s)-[rel:SISTER_OF]->(:Suspect {name: 'Clara'})
OPTIONAL MATCH (s)-[noalibi:HAS_NO]->(:Clue {name: 'Alibi'})
WITH
s.name AS suspect, v.name as victim, p.name AS crimeScene,
COUNT(DISTINCT weapon)*4 AS weaponScore,
COUNT(DISTINCT seenloc)*3 AS atCrimeSceneScore,
COUNT(DISTINCT argued)*2.5 AS motiveScore,
COUNT(DISTINCT delcctv)*2.5 AS tamperScore,
COUNT(DISTINCT glove)*2 AS gloveScore,
COUNT(DISTINCT noalibi)*2 AS noAlibiScore,
COUNT(DISTINCT rel)*1 AS relationScore
WITH suspect,
weaponScore + atCrimeSceneScore + motiveScore + tamperScore + gloveScore + noAlibiScore + relationScore AS totalSuspicion
ORDER BY totalSuspicion DESC
RETURN suspect AS LikelyCulprit, totalSuspicion
LikelyCulprit | totalSuspicion |
Clara | 7 |
Rita | 3.5 |
Elena | 2.5 |
Mark | 2 |
Tom | 2 |
Based on the results, Clara and Rita were the top two suspects.
When Detective Monroe confronted Clara with the fingerprint, the truth spilled out. Clara had worked in that library for 18 years. Finch had belittled her, insulted her dedication, and dismissed her as little more than a clerk. That night, during yet another confrontation, something inside her gave way. One moment of rage and one fatal blow. But it wasn’t planned, it was an accident.
There was a strong suspicion on Rita as well. Turns out that Rita had walked onto the scene and had panicked. She knew Clara wouldn’t survive a scandal like this. So, she tried to protect her sister. She took a glove from Mark’s supplies, staged it in the basement, and deleted the surveillance footage. She even lied about seeing Mark in the basement, hoping that somehow this lie would divert attention from her sister. It almost did.
In the end, both sisters were arrested—Clara for involuntary manslaughter, Rita for obstruction of justice. Mark, wrongly accused, was pained by this whole incident and left town without a word. Elena finished her thesis, dedicating it to those who break under pressure.
The library eventually reopened. The reading room was cleaned. The books were reshelved. But the silence felt different now—the weight of the memory of that Thursday evening fell on the shadows looming on the tall walls. If you stand there long enough, you might still hear it.