Logic Programming

advanced10 minlogic-programming.ts

Some answers must be derived by rules, not guessed: family relations, pricing tiers, discounts.

What it shows

  • Load Prolog-style facts and rules with createKnowledgeBase()
  • Query with queryKnowledgeBase(), add facts with assert()
  • Use arithmetic, cut and findall

The code

logic-programming.ts
import { createKnowledgeBase, formatSolutions, queryKnowledgeBase } from '@cogitator-ai/neuro-symbolic';

const kb = createKnowledgeBase();

const loaded = kb.consult(`
  parent(tom, bob).
  parent(tom, liz).
  parent(bob, ann).
  parent(bob, pat).
  parent(pat, jim).
  male(tom).
  male(bob).
  female(pat).

  father(X, Y) :- parent(X, Y), male(X).
  grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
  ancestor(X, Y) :- parent(X, Y).
  ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).
`);
if (!loaded.success) throw new Error(`Parse errors: ${JSON.stringify(loaded.errors)}`);

for (const query of ['father(X, bob)', 'grandparent(tom, X)', 'ancestor(tom, X)']) {
  console.log(`${query} => ${formatSolutions(queryKnowledgeBase(kb, query))}`);
}

kb.assert('parent(jim, sam).');
console.log('Is Tom an ancestor of Sam?', queryKnowledgeBase(kb, 'ancestor(tom, sam)').success);

const pricing = createKnowledgeBase(`
  price(laptop, 1200).
  price(mouse, 25).
  price(monitor, 300).
  discount(Total, D) :- ( Total >= 1000 -> D is Total * 0.1 ; D = 0 ).
  tier(P, premium) :- P >= 1000, !.
  tier(P, standard) :- P >= 100, !.
  tier(_, budget).
`);

console.log(formatSolutions(queryKnowledgeBase(pricing, 'findall(P, price(_, P), Ps), sum_list(Ps, Total), discount(Total, D)')));
console.log(formatSolutions(queryKnowledgeBase(pricing, 'price(Item, P), tier(P, Tier)')));

Run it

install · bash
pnpm add @cogitator-ai/neuro-symbolic
run · bash
npx tsx logic-programming.ts

Or run the full example from a clone of the repository (keys in .env):

repository · bash
npx tsx examples/advanced/02-neuro-symbolic.ts

Learn more