Below you will find pages that utilize the taxonomy term “Fuzzy-Logic-Search”
fuzzy-logic-search: Query Documents with Fuzzy Logic
November 30, 2025
fuzzy-logic-search (fls) brings fuzzy logic to document querying. Unlike traditional Boolean search that returns binary relevant/not-relevant results, fls produces a degree-of-membership score in [0, 1], indicating how well each document matches your query.
The Problem with Boolean Search
Boolean search is rigid: a document either matches or it does not. If you search for “python AND machine-learning,” you get a binary split. A document about Python ML that never uses the exact term “machine-learning” gets zero, same as a document about medieval pottery.
Fuzzy logic captures the gradation that Boolean search throws away.
from fuzzy_logic_search.fuzzy_query import FuzzyQuery
from fuzzy_logic_search.fuzzy_set import FuzzySet
# Construct a query
query = FuzzyQuery("(and python machine-learning)")
# Or use Python operators
q1 = FuzzyQuery("python")
q2 = FuzzyQuery("machine-learning")
query = q1 & q2 # Equivalent to (and python machine-learning)
Query Language
Queries use a Lisp-like syntax that maps to an AST:
; Simple conjunction
(and cat dog)
; With negation
(and cat dog (not fish))
; With fuzzy modifiers
(very (and cat dog))
; Complex nested query
(or (and python ml) (very (not java)))
Or construct directly with Python:
# Using operators
query = FuzzyQuery("cat") & FuzzyQuery("dog") & ~FuzzyQuery("fish")
# Using AST directly
query = FuzzyQuery(['and', 'cat', 'dog', ['not', 'fish']])
I went with S-expressions for the query language because they map directly to the AST. No parsing ambiguity, trivial to serialize, and anyone who has written a Lisp evaluator can understand the implementation in about ten minutes.
Fuzzy Modifiers
Linguistic hedges transform membership values:
# "Very" squares the membership (emphasizes strong matches)
very_query = FuzzyQuery("python").very()
# 0.9 -> 0.81, 0.5 -> 0.25
# "Somewhat" takes square root (broadens tolerance)
somewhat_query = FuzzyQuery("python").somewhat()
# 0.9 -> 0.95, 0.25 -> 0.5
# "Extremely" cubes the membership
extremely_query = FuzzyQuery("python").extremely()
# "Slightly" takes 10th root
slightly_query = FuzzyQuery("python").slightly()
These come from Zadeh’s original fuzzy logic work. “Very” is concentration (squaring), “somewhat” is dilation (square root). They are mathematically clean and semantically intuitive: “very python” means “only documents that are strongly about Python.”
Evaluating Queries
Evaluate queries against a document corpus:
# Documents as lists of terms
docs = [
["python", "machine-learning", "tensorflow"],
["java", "spring", "microservices"],
["python", "web", "flask"],
["machine-learning", "neural-networks", "pytorch"]
]
# Evaluate query
query = FuzzyQuery("python") & FuzzyQuery("machine-learning")
result = query.evaluate(docs) # Returns FuzzySet
# result.memberships = [1.0, 0.0, 0.0, 0.0]
# Only first document has both terms
Custom Membership Functions
The default membership is crisp (term present or not), but you can provide custom functions for more nuanced matching: