Knowledge representation & expert systems

Not every AI system learns from data. Many important systems encode what human experts already know as facts and rules, then reason over them. Tax software, insurance underwriting, medical triage checklists and eligibility engines for government schemes all work this way — and they are attractive precisely because every decision can be explained line by line.

Ways to represent knowledge

Form Idea Example
Propositional / predicate logic Statements that are true or false, with variables and quantifiers supplies_goods(shop) AND turnover > 40L
Production rules IF conditions THEN conclusion IF fever AND rash THEN suspect viral infection
Semantic network Nodes joined by labelled relations Mango --is-a--> Fruit --grown-in--> Ratnagiri
Frames / objects Slots with default values for a concept Loan: tenure = 60 months by default
Ontology / knowledge graph Shared vocabulary of entities and relations, queryable Product catalogue linked to brands and categories

Anatomy of an expert system

Three parts, kept deliberately separate:

  1. Knowledge base — the rules, written and reviewed by domain experts.
  2. Working memory — the facts known about the current case.
  3. Inference engine — the code that decides which rules fire and in what order.

Because the rules live outside the code, a GST consultant can update a threshold without a developer touching the inference engine.

Forward chaining in 15 lines

Forward chaining starts from known facts and keeps firing rules until nothing new can be derived (data-driven). Backward chaining starts from a goal and works backwards to see which facts would prove it (goal-driven).

RULES = [
    ({"supplies_goods", "turnover_above_40l"}, "must_register_for_gst"),
    ({"supplies_services", "turnover_above_20l"}, "must_register_for_gst"),
    ({"must_register_for_gst"}, "files_monthly_returns"),
    ({"files_monthly_returns", "no_accountant"}, "needs_filing_support"),
]

def forward_chain(facts, rules):
    facts = set(facts)
    changed = True
    while changed:
        changed = False
        for conditions, conclusion in rules:
            if conditions <= facts and conclusion not in facts:
                facts.add(conclusion)
                changed = True
    return facts

case = {"supplies_goods", "turnover_above_40l", "no_accountant"}
print(sorted(forward_chain(case, RULES)))

Add a trace (record which rule added which fact) and you get a free explanation: "You need filing support because you must register for GST, which means monthly returns, and you have no accountant."

Rules or machine learning?

Prefer rules when the logic is written down somewhere (law, policy, SOP), decisions must be auditable, and there is little labelled data. Prefer learning when the pattern is fuzzy, examples are plentiful, and nobody can state the rule precisely — recognising a damaged parcel from a photo, for instance. Many production systems combine both: a model scores the case, and hard rules veto anything the policy forbids.

Common mistakes

  • Letting the rule base grow to thousands of overlapping rules with no tests; contradictions creep in silently.
  • Hard-coding thresholds in Python instead of keeping them as editable data.
  • No conflict-resolution strategy when two rules fire and disagree.
  • Assuming a rule engine is "not real AI" — auditability is often worth more than accuracy.

Practice

Write 8 rules for a scholarship-eligibility system (income band, marks, category, state of domicile). Extend forward_chain so it also returns the list of rules that fired, and print a plain-English explanation for one approved and one rejected applicant.

B

Written by Bablu Kumar Jha

Founder, BeeProton AI · Mumbai, Maharashtra, India