Skip to content

Commit

Permalink
More logic factors, check for duplicate nodes, network info text (#66)
Browse files Browse the repository at this point in the history
* check for duplicate node names, improve error handling
* split up logic code
* make logic factor pointer interface
* add weekday puzzle
* add counting and indexing logic
* rename logic index to given
* add logic for indices
* add new examples to CI
* rename logic index to outcome
* add more counting logic
* add more outcome logic
* add friends example
* networks can have an intro text
  • Loading branch information
mlange-42 authored Jul 4, 2024
1 parent a368bc9 commit 564a2ff
Show file tree
Hide file tree
Showing 25 changed files with 1,190 additions and 173 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,14 @@ jobs:
run: go build ./cmd/bbn
- name: Run CLI examples
run: |
./bbn inference _examples/logic/friends.yml
./bbn inference _examples/logic/knights.yml
./bbn inference _examples/logic/weekday.yml
./bbn inference _examples/asia.yml
./bbn inference _examples/disease-control.yml
./bbn inference _examples/dog-problem.xml
./bbn inference _examples/earthquake.yml
./bbn inference _examples/disease-control.yml
./bbn train _examples/fruits-untrained.yml _examples/fruits.csv
./bbn inference _examples/medical-treatment.yml
./bbn inference _examples/mendel.yml
./bbn inference _examples/monty-hall.yml
Expand All @@ -84,4 +88,3 @@ jobs:
./bbn inference _examples/robot.yml
./bbn inference _examples/sprinkler.yml
./bbn inference _examples/umbrella.yml
./bbn train _examples/fruits-untrained.yml _examples/fruits.csv
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
* Optional total utility node for weighting individual utilities (#59)
* Adds support for custom node colors in YAML files (#64)
* Adds shortcuts for logic nodes like, and, or, if-then, etc. (#65)
* Networks can have a longer info text, also shown in TUI app (#65)

### Documentation

* Adds oil drilling decision example (#48)
* Adds robot decision example (#50)
* Adds medical treatment decision example (#60)
* Adds disease control decision example (#61)
* Adds several examples for logic deduction (#65)
* Adds several examples for logic deduction (#65, #66)

## [[v0.4.0]](https://github.com/mlange-42/bbn/compare/v0.3.0...v0.4.0)

Expand Down
97 changes: 97 additions & 0 deletions _examples/logic/friends.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: Who is right?
info: >-
Four friends A, B, C and D meet and state the quoted facts below.
Who is right, and who is wrong?
Activate the ==> in the blue node to solve.
variables:

- variable: A
position: [1, 0]
outcomes: [right, wrong]
table:
- [50, 50]

- variable: B
position: [33, 0]
outcomes: [right, wrong]
table:
- [50, 50]

- variable: C
position: [65, 0]
outcomes: [right, wrong]
table:
- [50, 50]

- variable: D
position: [97, 0]
outcomes: [right, wrong]
table:
- [50, 50]

- variable: Count correct
position: [49, 8]
outcomes: [0, 1, 2, 3, 4]
given: [A, B, C, D]
logic: count-true

- variable: '"Two are right"'
position: [1, 17]
outcomes: [=>, " "]
given: [A, Count == 2]
logic: bicond

- variable: '"Max. two are right"'
position: [33, 17]
outcomes: [=>, " "]
given: [B, Count <= 3]
logic: bicond

- variable: '"B is wrong"'
position: [65, 17]
outcomes: [=>, " "]
given: [C, B is wrong]
logic: bicond

- variable: '"Max. one is right"'
position: [97, 17]
outcomes: [=>, " "]
given: [D, Count <= 1]
logic: bicond

- variable: Count == 2
position: [3, 24]
outcomes: [right, wrong]
given: [Count correct]
logic: outcome-is 2 5

- variable: Count <= 3
position: [4, 29]
outcomes: [right, wrong]
given: [Count correct]
logic: outcome-less 3 5

- variable: B is wrong
position: [95, 24]
outcomes: [right, wrong]
given: ['"Max. two are right"']
logic: not

- variable: Count <= 1
position: [94, 29]
outcomes: [right, wrong]
given: [Count correct]
logic: outcome-less 2 5

- variable: Trigger
position: [49, 24]
color: blue
outcomes: [==>, " "]
given:
- '"Two are right"'
- '"Max. two are right"'
- '"B is wrong"'
- '"Max. one is right"'
logic: count-is 4
20 changes: 0 additions & 20 deletions _examples/logic/hypothetical-syllogism.yml

This file was deleted.

12 changes: 11 additions & 1 deletion _examples/logic/knights.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
name: Knights and Knaves
info: >-
A classical Knights and Knaves puzzle.
Knights always say the truth, while knaves always lie.
Person A says "We are both knaves".
Can you derive who is what?
Activate the ==> in the blue node to solve.
variables:

- variable: A
Expand All @@ -22,6 +32,6 @@ variables:
- variable: We are both knaves
position: [1, 8]
color: blue
outcomes: [yes, no]
outcomes: [==>, " "]
given: [A, A knave && B knave]
logic: bicond
72 changes: 72 additions & 0 deletions _examples/logic/weekday.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Weekday 7 friends puzzle
info: >-
Seven friends meet, and are not sure which day of the week it is.
Each one has a guess, but only one is right.
Which day of the week is it?
Activate the ==> in the blue node to solve.
variables:

- variable: Day of week
position: [41, 0]
color: lime
outcomes: [Mon, Tue, Wed, Thu, Fri, Sat, Sun]
table:
- [1, 1, 1, 1, 1, 1, 1]

- variable: '"It is Monday"'
position: [1, 13]
given: [Day of week]
outcomes: [yes, no]
logic: outcome-is 0 7

- variable: '"It is Tuesday"'
position: [28, 11]
given: [Day of week]
outcomes: [yes, no]
logic: outcome-is 1 7

- variable: '"It is Wednesday"'
position: [55, 11]
given: [Day of week]
outcomes: [yes, no]
logic: outcome-is 2 7

- variable: '"It is Thursday or Friday"'
position: [82, 13]
given: [Day of week]
outcomes: [yes, no]
logic: outcome-either 3 4 7

- variable: '"It is Sunday"'
position: [2, 19]
given: [Day of week]
outcomes: [yes, no]
logic: outcome-is 6 7

- variable: '"Tomorrow is Monday"'
position: [41, 18]
given: [Day of week]
outcomes: [yes, no]
logic: outcome-is 6 7

- variable: '"It is not Sunday"'
position: [81, 19]
given: [Day of week]
outcomes: [yes, no]
logic: outcome-is-not 6 7

- variable: "Exactly one is correct "
position: [39, 25]
color: blue
outcomes: [==>, " "]
given:
- '"It is Monday"'
- '"It is Tuesday"'
- '"It is Wednesday"'
- '"It is Thursday or Friday"'
- '"It is Sunday"'
- '"Tomorrow is Monday"'
- '"It is not Sunday"'
logic: count-is 1
5 changes: 4 additions & 1 deletion examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ func Example_sprinkler() {
},
}

net := bbn.New("Sprinkler", variables, factors)
net, err := bbn.New("Sprinkler", "", variables, factors)
if err != nil {
panic(err)
}

evidence := map[string]string{
"GrassWet": "yes",
Expand Down
49 changes: 44 additions & 5 deletions internal/tui/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type App struct {
table *tview.Table
helpDialog *tview.Grid
help *tview.TextView
infoDialog *tview.Grid
info *tview.TextView
canvas [][]rune
colors [][]Color
network *bbn.Network
Expand Down Expand Up @@ -102,17 +104,28 @@ func (a *App) Run() error {
a.helpDialog = a.createHelpPanel()
a.pages.AddPage("Help", a.helpDialog, true, false)

a.infoDialog = a.createInfoPanel()
a.pages.AddPage("Info", a.infoDialog, true, false)

mainPanel.SetInputCapture(a.inputMainPanel)
a.graph.SetMouseCapture(a.mouseInputGraph)

a.table.SetInputCapture(a.inputTable)
a.table.SetMouseCapture(a.mouseInputTable)
a.graph.SetMouseCapture(a.mouseInputGraph)

a.help.SetInputCapture(a.inputHelp)
a.help.SetMouseCapture(a.mouseInputHelp)

a.info.SetInputCapture(a.inputInfo)
a.info.SetMouseCapture(a.mouseInputInfo)

a.app.SetFocus(a.graph)
rooted := a.app.SetRoot(a.pages, true)
a.showInfo()

if err := a.app.SetRoot(a.pages, true).Run(); err != nil {
if err := rooted.Run(); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -156,10 +169,13 @@ func (a *App) createWidgets() {
Navigate bars Space/Numbers
Toggle evidence Enter left click
Show table T right click
Ignore policies I
Ignore policies P
Move node W/A/S/D
Save network Ctrl+S
`)
a.info = tview.NewTextView().
SetWrap(true).
SetText(a.network.Info())
}

func (a *App) createMainPanel() *tview.Grid {
Expand All @@ -177,7 +193,7 @@ func (a *App) createMainPanel() *tview.Grid {

help := tview.NewTextView().
SetWrap(false).
SetText("Press H for help!")
SetText("Press H for help, I for network info!")
grid.AddItem(help, 2, 0, 1, 2, 0, 0, false)

return grid
Expand Down Expand Up @@ -227,3 +243,26 @@ func (a *App) createHelpPanel() *tview.Grid {

return grid
}

func (a *App) createInfoPanel() *tview.Grid {
grid := tview.NewGrid().
SetColumns(0, 72, 0).
SetRows(0, 17, 0)

subGrid := tview.NewGrid().
SetColumns(0).
SetRows(0, 1)
subGrid.SetBorder(true)
subGrid.SetTitle(" Info ")

subGrid.AddItem(a.info, 0, 0, 1, 1, 0, 0, true)

info := tview.NewTextView().
SetWrap(false).
SetText(" Close info: ESC Scroll: ←→↕")
subGrid.AddItem(info, 1, 0, 1, 1, 0, 0, false)

grid.AddItem(subGrid, 1, 1, 1, 1, 0, 0, false)

return grid
}
Loading

0 comments on commit 564a2ff

Please sign in to comment.