diff --git a/examples/wordle/Makefile b/examples/wordle/Makefile
new file mode 100644
index 0000000..2ad4a02
--- /dev/null
+++ b/examples/wordle/Makefile
@@ -0,0 +1,21 @@
+BASE := today
+
+TEST = 1
+
+words.ptable.tsv: word-probs.csv
+ perl make-ptable-from-words.pl $< > $@
+letters.ptable.tsv: letter-freqs.csv
+ perl make-ptable-from-letter-freqs.pl $< > $@
+today.ptable.tsv: words.ptable.tsv letters.ptable.tsv
+ cat $^ > $@
+
+ont-%.pre: my-guesses-%.csv
+ perl guesses2owl.pl $< > $@
+
+ont-%.omn: ont-%.pre
+ cat wordle.omn $< > $@
+
+today.owl: ont-$(TEST).omn
+ cp $< $@
+
+include ../Makefile
diff --git a/examples/wordle/README.md b/examples/wordle/README.md
new file mode 100644
index 0000000..e8a1b1c
--- /dev/null
+++ b/examples/wordle/README.md
@@ -0,0 +1,80 @@
+# Boomerdle
+
+NOT WORKING
+
+aims to show how boomer can be used to find most likely Wordle answers.
+
+## Background knowledge
+
+[letter-freqs.csv](letter-freqs.csv):
+
+```
+A, 0.05, 0.05, 0.05, 0.05, 0.05
+B, 0.05, 0.05, 0.05, 0.05, 0.05
+C, 0.05, 0.05, 0.05, 0.05, 0.05
+```
+
+this is the prior chance of a letter being present at positions 1-5. Currently seeded at equal probs but this could be changed, e.g. Q lower.
+
+probabilities of pairwise, e.g Q-followed-by-not-U is not supported
+
+This is compiled to a ptable [letters.ptable.tsv](letters.ptable.tsv) by [make-ptable-from-words.pl](make-ptable-from-words.pl)
+
+```
+✗ less word-probs.csv
+bunch, 0.001
+canoe, 0.001
+stair, 0.001
+stare, 0.001
+dance, 0.001
+zebra, 0.0005
+```
+
+this is just a demo set. Could be expanded using any dictionary plus info on frequencies
+
+This is converted to words.ptable.tsv
+
+## Logical Axioms
+
+### Background Knowledge
+
+[wordle.omn](wordle.omn)
+
+### Guesses so far
+
+These go in:
+
+my-guesses-N.csv
+
+the 2nd colum is the wordle feedback (G=green, O=organe)
+
+These are translated into logical axioms (combined with the list of all words)
+
+canoe, OxGxx
+
+=>
+
+```owl
+Class: soln:canoe DisjointWith: :TodaysWord
+Class: :TodaysWord SubClassOf: :hasLetter some :C
+Class: :TodaysWord DisjointWith: :hasLetter1 some :C
+Class: :TodaysWord DisjointWith: :hasLetter some :A
+Class: :TodaysWord SubClassOf: :hasLetter3 some :N
+Class: :TodaysWord DisjointWith: :hasLetter some :O
+Class: :TodaysWord DisjointWith: :hasLetter some :E
+Class: soln:bunch
+Class: soln:canoe
+Class: soln:stair
+Class: soln:stare
+Class: soln:dance
+Class: soln:zebra
+Class: :TodaysWord DisjointUnionOf: soln:bunch, soln:canoe, soln:stair, soln:stare, soln:dance, soln:zebra
+Class: :TodaysWord SubClassOf: soln:bunch OR soln:canoe OR soln:stair OR soln:stare OR soln:dance OR soln:zebra
+```
+
+## Boomer
+
+all ptables and owl is combined and boomer is run
+
+currently Whelk doesn't support DisjointUnionOf so we can't 'close the world', and boomer gives the most likely answer
+as being *none* of the candidate words, so it refuses to play and pick one (not unlike the computer in wargames).
diff --git a/examples/wordle/guesses2owl.pl b/examples/wordle/guesses2owl.pl
new file mode 100755
index 0000000..621f711
--- /dev/null
+++ b/examples/wordle/guesses2owl.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/perl
+use strict;
+
+#print "Prefix: : \n";
+#print "Prefix: soln: \n";
+
+#print "## Constraints from guesses\n";
+#print "Ontology: \n\n";
+
+
+while (<>) {
+ chomp;
+ my ($w, $result) = split(/,\s+/, $_);
+ $w = lc($w);
+ # we rule out the word in its entirety
+ print "Class: soln:$w DisjointWith: :TodaysWord\n";
+ for my $i (0..4) {
+ my $n = $i+1;
+ my $letter = uc(substr($w,$i,1));
+ my $letter_result = substr($result,$i,1);
+ if ($letter_result eq 'x') {
+ print "Class: :TodaysWord DisjointWith: :hasLetter some :$letter\n";
+ }
+ elsif ($letter_result eq 'G') {
+ print "Class: :TodaysWord SubClassOf: :hasLetter$n some :$letter\n";
+ }
+ elsif ($letter_result eq 'O') {
+ print "Class: :TodaysWord SubClassOf: :hasLetter some :$letter\n";
+ print "Class: :TodaysWord DisjointWith: :hasLetter$n some :$letter\n";
+ }
+ else {
+ die "Word: $w results: $result index: $i == $letter_result";
+ }
+ }
+}
+open(F, 'word-probs.csv');
+my @words = ();
+while () {
+ chomp;
+ s@,.*@@;
+ my $c = "soln:$_";
+ push(@words, $c);
+ print "Class: $c\n";
+}
+close(F);
+my $wstr = join(', ', @words);
+my $union = join(' OR ', @words);
+# whelk doesn't support:
+print "Class: :TodaysWord DisjointUnionOf: $wstr\n";
+print "Class: :TodaysWord SubClassOf: $union\n";
diff --git a/examples/wordle/letter-freqs.csv b/examples/wordle/letter-freqs.csv
new file mode 100644
index 0000000..5bbdb1f
--- /dev/null
+++ b/examples/wordle/letter-freqs.csv
@@ -0,0 +1,26 @@
+A, 0.05, 0.05, 0.05, 0.05, 0.05
+B, 0.05, 0.05, 0.05, 0.05, 0.05
+C, 0.05, 0.05, 0.05, 0.05, 0.05
+D, 0.05, 0.05, 0.05, 0.05, 0.05
+E, 0.05, 0.05, 0.05, 0.05, 0.05
+F, 0.05, 0.05, 0.05, 0.05, 0.05
+G, 0.05, 0.05, 0.05, 0.05, 0.05
+H, 0.05, 0.05, 0.05, 0.05, 0.05
+I, 0.05, 0.05, 0.05, 0.05, 0.05
+J, 0.05, 0.05, 0.05, 0.05, 0.05
+K, 0.05, 0.05, 0.05, 0.05, 0.05
+L, 0.05, 0.05, 0.05, 0.05, 0.05
+M, 0.05, 0.05, 0.05, 0.05, 0.05
+N, 0.05, 0.05, 0.05, 0.05, 0.05
+O, 0.05, 0.05, 0.05, 0.05, 0.05
+P, 0.05, 0.05, 0.05, 0.05, 0.05
+Q, 0.05, 0.05, 0.05, 0.05, 0.05
+R, 0.05, 0.05, 0.05, 0.05, 0.05
+S, 0.05, 0.05, 0.05, 0.05, 0.05
+T, 0.05, 0.05, 0.05, 0.05, 0.05
+U, 0.05, 0.05, 0.05, 0.05, 0.05
+V, 0.05, 0.05, 0.05, 0.05, 0.05
+W, 0.05, 0.05, 0.05, 0.05, 0.05
+X, 0.05, 0.05, 0.05, 0.05, 0.05
+Y, 0.05, 0.05, 0.05, 0.05, 0.05
+Z, 0.05, 0.05, 0.05, 0.05, 0.05
diff --git a/examples/wordle/make-ptable-from-letter-freqs.pl b/examples/wordle/make-ptable-from-letter-freqs.pl
new file mode 100755
index 0000000..0c141b9
--- /dev/null
+++ b/examples/wordle/make-ptable-from-letter-freqs.pl
@@ -0,0 +1,14 @@
+#!/usr/bin/perl
+use strict;
+
+open(F,'letter-freqs.csv');
+while () {
+ chomp;
+ my ($letter,@rest) = split(/,\s*/, $_);
+ for my $i (0..4) {
+ my $n = $i+1;
+ my $p = $rest[$i];
+ my $np = 1-$p;
+ print "wordle:$letter\twordle:Letter$n\t$p\t0\t0\t$np\n";
+ }
+}
diff --git a/examples/wordle/make-ptable-from-words.pl b/examples/wordle/make-ptable-from-words.pl
new file mode 100644
index 0000000..4446e52
--- /dev/null
+++ b/examples/wordle/make-ptable-from-words.pl
@@ -0,0 +1,13 @@
+#!/usr/bin/perl
+use strict;
+
+open(F,'word-probs.csv');
+while () {
+ chomp;
+ my ($w,$p) = split(/,\s*/, $_);
+ if (!$p) {
+ $p = '0.0001';
+ }
+ my $np = 1-$p;
+ print "soln:$w\twordle:TodaysWord\t0\t0\t$p\t$np\n";
+}
diff --git a/examples/wordle/my-guesses-1.csv b/examples/wordle/my-guesses-1.csv
new file mode 100644
index 0000000..37e2790
--- /dev/null
+++ b/examples/wordle/my-guesses-1.csv
@@ -0,0 +1 @@
+canoe, OxGxx
diff --git a/examples/wordle/prefixes.yaml b/examples/wordle/prefixes.yaml
new file mode 100644
index 0000000..7521633
--- /dev/null
+++ b/examples/wordle/prefixes.yaml
@@ -0,0 +1,3 @@
+wordle: http://example.org/wordle/
+soln: http://example.org/soln/
+
diff --git a/examples/wordle/true-answer-1.csv b/examples/wordle/true-answer-1.csv
new file mode 100644
index 0000000..4f454c3
--- /dev/null
+++ b/examples/wordle/true-answer-1.csv
@@ -0,0 +1 @@
+bunch
diff --git a/examples/wordle/word-probs.csv b/examples/wordle/word-probs.csv
new file mode 100644
index 0000000..8e44665
--- /dev/null
+++ b/examples/wordle/word-probs.csv
@@ -0,0 +1,6 @@
+bunch, 0.001
+canoe, 0.001
+stair, 0.001
+stare, 0.001
+dance, 0.001
+zebra, 0.0005
diff --git a/examples/wordle/wordle.omn b/examples/wordle/wordle.omn
new file mode 100644
index 0000000..2b0397b
--- /dev/null
+++ b/examples/wordle/wordle.omn
@@ -0,0 +1,74 @@
+Prefix: :
+Prefix: soln:
+
+## Wordle
+Ontology:
+
+
+ObjectProperty: :hasLetter
+ObjectProperty: :hasLetter1
+ Characteristics: Functional
+ SubPropertyOf: :hasLetter
+ObjectProperty: :hasLetter2
+ Characteristics: Functional
+ SubPropertyOf: :hasLetter
+ObjectProperty: :hasLetter3
+ Characteristics: Functional
+ SubPropertyOf: :hasLetter
+ObjectProperty: :hasLetter4
+ Characteristics: Functional
+ SubPropertyOf: :hasLetter
+ObjectProperty: :hasLetter5
+ Characteristics: Functional
+ SubPropertyOf: :hasLetter
+
+Class: :Letter
+ DisjointUnionOf: :A, :B, :C, :D, :E, :F, :G, :H, :I, :J, :K, :L, :M, :N, :O, :P, :Q, :R, :S, :T, :U, :V, :W, :X, :Y, :Z
+ SubClassOf: :A OR :B OR :C OR :D OR :E OR :F OR :G OR :H OR :I OR :J OR :K OR :L OR :M OR :N OR :O OR :P OR :Q OR :R OR :S OR :T OR :U OR :V OR :W OR :X OR :Y OR :Z
+Class: :A SubClassOf: :Letter
+Class: :B SubClassOf: :Letter
+Class: :C SubClassOf: :Letter
+Class: :D SubClassOf: :Letter
+Class: :E SubClassOf: :Letter
+Class: :F SubClassOf: :Letter
+Class: :G SubClassOf: :Letter
+Class: :H SubClassOf: :Letter
+Class: :I SubClassOf: :Letter
+Class: :J SubClassOf: :Letter
+Class: :K SubClassOf: :Letter
+Class: :L SubClassOf: :Letter
+Class: :M SubClassOf: :Letter
+Class: :N SubClassOf: :Letter
+Class: :O SubClassOf: :Letter
+Class: :P SubClassOf: :Letter
+Class: :Q SubClassOf: :Letter
+Class: :R SubClassOf: :Letter
+Class: :S SubClassOf: :Letter
+Class: :T SubClassOf: :Letter
+Class: :U SubClassOf: :Letter
+Class: :V SubClassOf: :Letter
+Class: :W SubClassOf: :Letter
+Class: :X SubClassOf: :Letter
+Class: :Y SubClassOf: :Letter
+Class: :Z SubClassOf: :Letter
+
+Class: :Letter1
+ SubClassOf: :Letter
+Class: :Letter2
+ SubClassOf: :Letter
+Class: :Letter3
+ SubClassOf: :Letter
+Class: :Letter4
+ SubClassOf: :Letter
+Class: :Letter5
+ SubClassOf: :Letter
+
+
+Class: :TodaysWord
+ SubClassOf: :hasLetter1 some :Letter1, :hasLetter1 only :Letter1
+ SubClassOf: :hasLetter2 some :Letter2, :hasLetter2 only :Letter2
+ SubClassOf: :hasLetter3 some :Letter3, :hasLetter3 only :Letter3
+ SubClassOf: :hasLetter4 some :Letter4, :hasLetter4 only :Letter4
+ SubClassOf: :hasLetter5 some :Letter5, :hasLetter5 only :Letter5
+
+