examples/familly_tree.livemd

# Family Tree

```elixir
Mix.install([
  {:guesswork, "~> 0.7"},
  {:kino, "~> 0.13"}
])
```

## Build a Knowledge Base

Describing family trees is often used as the 'Hello World' of logical programming,
so this example will show you how to build a Knowledge Base and query it.

```elixir
import Guesswork.Ast

alias Guesswork.Ast.And
alias Guesswork.Ast.Fact
alias Guesswork.Answer.Result
```

Start by adding rules and concrete facts to the knowledge base, in this case parent 
child relationships and grandparent realtionships defined as parent relationships.

```elixir
defmodule KB do
  use Guesswork.KnowledgeBase.Collection

  deffact parent(:bob, :joe)
  deffact parent(:bob, :jean)
  deffact parent(:mary, :joe)
  deffact parent(:bobby, :jean)

  deffact parent(:christy, :bob)
  deffact parent(:lance, :bob)

  deffact parent(:billy, :christy)
  deffact parent(:meg, :lanceb)

  defrule grandparent(gp, gc) do 
    Fact.new(:parent, [gp, p])
    Fact.new(:parent, [p, gc])
  end
end
```

## Query the System

Now you can query the system.
This first query is simplier since it only asks questions of the
concrete facts stored in the knowledge base; in this case what are
bob's children.

```elixir
Guesswork.query(term(Fact.new(:parent, [:bob, child])), 10, knowledge_base: KB)
```

You can also ask more complex questions, like what are all the grandparents
of joe.
You should note that the variable internal to the grandparent rule (`p`) is not
part of the final answer set.
This is because `Guesswork` respects lexical scoping of variables.

```elixir
Guesswork.query(term(Fact.new(:grandparent, [gp, :joe])), 100, knowledge_base: KB)
```