Game Tree modulo Symmetry in Prolog - search

Lets work out a game tree for Tic-Tac-Toe. How
would one compute this result in Prolog:
Taking the 8 symmetries into account, and assuming computer (X) starts
and plays deterministic, then only 49 table entries are needed!
1 entry for empty board
5 entries for 2 pieces
21 entries for 4 pieces
18 entries for 6 pieces
4 entries for 8 pieces
https://stackoverflow.com/a/61298546/502187

Using an adaptation of the algorithm here, I get
a shorter solution with only 37 game positions:
?- init(X), best(X, x, L, W),
findall(Z, inside(L, Z), A),
sort(A, B), length(B, N).
B = [[[-, -, -], [-, x, -], [-, -, -]], [[x, -, o],
[-, x, -], [-, -, -]], [[x, -, o], [-, x, x], [-, -, o]],
[[x, o, -], [-, x, -], [-, -, -]], [[x, o, -], [-, x, -],
[-, o, x]], [[x, o, -], [-, x, -], [x, -, o]], [[x, o, -],
[-, x, o], [-, -, x]], [[x, o, -], [-, x, x], [o, -, -]],
[[x, o, -], [o, x, -], [-, -, x]], [[x, o, o], [-, x, -],
[-, -, x]], [[x, o, o], [-, x, -], [x, -, -]], [[x, o, o],
[-, x, o], [x, -, x]], [[x, o, o], [-, x, x], [-, -, -]],
[[x, o, o], [-, x, x], [o, x, -]], [[x, o, o], [-, x, x],
[x, o, -]], [[x, o, x], [-, x, -], [o, x, o]], [[x, o, x],
[-, x, -], [x, o, o]], [[x, o, x], [o, x, -], [o, -, x]],
[[x, o, x], [o, x, -], [x, -, o]], [[x, x, -], [-, x, o],
[o, o, x]], [[x, x, -], [-, x, o], [o, x, o]], [[x, x, -],
[o, x, -], [o, x, o]], [[x, x, -], [o, x, o], [o, -, x]],
[[x, x, o], [-, x, -], [o, -, -]], [[x, x, o], [-, x, -],
[o, o, x]], [[x, x, o], [-, x, -], [o, x, o]], [[x, x, o],
[-, x, o], [-, o, x]], [[x, x, o], [-, x, o], [o, x, -]],
[[x, x, o], [o, x, -], [-, x, o]], [[x, x, o], [o, x, -],
[o, x, -]], [[x, x, o], [o, x, o], [-, x, -]], [[x, x, o],
[o, x, o], [x, o, x]], [[x, x, o], [o, x, x], [o, x, o]],
[[x, x, o], [o, x, x], [x, o, o]], [[x, x, o], [x, x, o],
[o, o, x]], [[x, x, x], [o, x, -], [o, -, o]],
[[x, x, x], [o, x, o], [o, x, o]]],
N = 37
But since best/4 uses random_member/2 to make the choice
deterministic, by rerunning, one gets also longer results.
Prolog code for the tic-tac-toe game
score via findall, return random winning strategy
reduce number of moves through symmetry
https://gist.github.com/jburse/928f060331ed7d5307a0d3fcd6d4aae9#file-tictac4-pl

It's a vague question with an incorrect premise:
assuming computer (X) starts and plays deterministic
OK
5 entries for 2 pieces
If the X starts in the center (deterministic), then there are only two distinct 2-piece positions:
_ _ _
O X _
_ _ _
O _ _
_ X _
_ _ _
HTH

Related

Lambda Calculus change of variable and application question

I am studying Haskell and I am learning what is an abstraction, substitution (beta equivalence), application, free and bound variables (alpha equivalence), but I have some doubts resolving these exercises, I don't know if my solutions are correct.
Make the following substitutions
1. (λ x → y x x) [x:= f z]
Sol. (\x -> y x x) =>α (\w -> y w w) =>α (\w -> x w w) =>β (\w -> f z w w)
2. ((λ x → y x x) x) [y:= x]
Sol. ((\x -> y x x)x) =>α (\w -> y w w)[y:= x] = (\w -> x w w)
3. ((λ x → y x) (λ y → y x) y) [x:= f y]
Sol. aproximation, i don't know how to do it: ((\x -> y x)(\y -> y x) y) =>β
(\x -> y x)y x)[x:= f y] =>β y x [x:= f y] = y f y
4. ((λ x → λ y → y x x) y) [y:= f z]
Sol aproximation, ((\x -> (\y -> (y x x))) y) =>β ((\y -> (y x x)) y) =>α ((\y -> (y x x)) f z)
Another doubt that I have is if can I run these expressions on this website? It is a Lambda Calculus Calculator but I do not know how to run these tests.
1. (λ x → y x x) [x:= f z]
Sol. (\x -> y x x) =>α (\w -> y w w) =>α (\w -> x w w) =>β (\w -> f z w w)
No, you can't rename y, it's free in (λ x → y x x). Only bound variables can be (consistently) α-renamed. But only free variables can be substituted, and there's no free x in that lambda term.
2. ((λ x → y x x) x) [y:= x]
Sol. ((\x -> y x x)x) =>α (\w -> y w w)[y:= x] = (\w -> x w w)
Yes, substituting x for y would allow it to be captured by the λ x, so you indeed must α-rename the x in (λ x → y x x) first to some new unique name as you did, but you've dropped the application to the free x for some reason. You can't just omit parts of a term, so it's ((\w -> y w w) x)[y:= x]. Now perform the substitution. Note you're not asked to perform the β-reduction of the resulting term, just the substitution.
I'll leave the other two out. Just follow the rules carefully. It's easy if you rename all bound names to unique names first, even if the renaming is not strictly required, for instance
((λ x → y x) (λ y → y x) y) [x:= f y] -->
((λ w → y w) (λ z → z x) y) [x:= f y]
The "unique" part includes also the free variables used in the substitution terms, that might get captured after being substituted otherwise (i.e. without the renaming being performed first, in the terms in which they are being substituted). That's why we had to rename the bound y in the above term, -- because y appears free in the substitution term. We didn't have to rename the bound x but it made it easier that way.

TPIL 4.4: example : ¬ (∃ x, ¬ p x) → (∀ x, p x)

Section 4.4 of Theorem Proving in Lean shows the following:
example : (∀ x, p x) ↔ ¬ (∃ x, ¬ p x) := sorry
Here I'll focus on the right-to-left case:
¬ (∃ x, ¬ p x) → (∀ x, p x)
Approach 1
We know that we'll have a parameter of type ¬ (∃ x, ¬ p x) so let's start with that:
example : ¬ (∃ x, ¬ p x) → (∀ x, p x) :=
(assume hnExnpx : ¬ (∃ x, ¬ p x),
_)
We know that we'll have to return an expression of type (∀ x, p x) so let's begin constructing that:
example : ¬ (∃ x, ¬ p x) → (∀ x, p x) :=
(assume hnExnpx : ¬ (∃ x, ¬ p x),
(λ x, _))
At this point we need to return a value of type p x and it isn't clear that we can build one at this point. Perhaps we need to try to come up with a false value.
The function hnExnpx returns false given a (∃ x, ¬ p x). So let's try to build one of those, apply hnExnpx to it and then use false.elim:
example : ¬ (∃ x, ¬ p x) → (∀ x, p x) :=
(assume hnExnpx : ¬ (∃ x, ¬ p x),
(λ x,
false.elim (hnExnpx (exists.intro x (λ hpx, _)))
))
And now we're back to needing another false value.
Approach 2
Chapter 3 mentioned that sometimes classical logic is needed.
A naive approach which uses (em (∀ x, p x)) leads us here:
example : ¬ (∃ x, ¬ p x) → (∀ x, p x) :=
(assume hnExnpx : ¬ (∃ x, ¬ p x),
or.elim (em (∀ x, p x))
(λ hAxpx, hAxpx)
(λ hnAxpx : ¬ (∀ x, p x), (λ x, _))
)
Again, we'll need a p x value or a false. The only new thing we have is hnAxpx : ¬∀ (x : α), p x. It's still not clear how to get a p x. hnAxpx does return false but we'd need a (∀ x, p x) which is the original thing we're looking for. :-)
Perhaps this one involves a more elaborate use of classical logic?
Any suggestions are welcome!
UPDATE
Here's an approach based on the comment by simon1505475 below which appears to work:
example : ¬ (∃ x, ¬ p x) → (∀ x, p x) :=
(assume hnExnpx : ¬ (∃ x, ¬ p x),
(λ x,
or.elim (em (p x))
(λ hpx : p x, hpx)
(λ hnpx : ¬ p x,
false.elim (hnExnpx (exists.intro x (λ hpx : p x, hnpx hpx))))))

How to remove a universal quantifier in Lean?

I am working with two binary relations: g_o and pw_o, and I've defined pw_o below:
constants {A : Type} (g_o : A → A → Prop)
def pw_o (x y : A) : Prop := ∀ w : A, (g_o w x → g_o w y) ∧ (g_o y w → g_o x w)
I need to prove the following:
theorem prelim: ∀ x y z : A, g_o x y ∧ pw_o y z → g_o x z :=
I start with these tactics:
begin
intros,
cases a with h1 h2,
end
And I have this:
x y z : A,
h1 : g_o x y,
h2 : pw_o y z
⊢ g_o x z
Since pw_o is defined with a universal quantifier, I'd like to substitute w with x, then I would have (g_o x y → g_o x z) ∧ (g_o z x → g_o y x). After isolating the first conjunct with the "cases" tactic, I can use modus ponens on that first conjunct and h1.
How can I tell Lean to replace w in the definition of pw_o with x and replace x and y in the definition of pw_o with y and z, respectively?
Elimination of the universal quantifier is basically just application,
so to substitute w, with x just apply x to the instance h2 of pw_o y z.
theorem prelim': ∀ x y z : A, g_o x y ∧ pw_o y z → g_o x z :=
begin
intros,
cases a with h1 h2,
cases h2 x with h3 _,
sorry
end

ghg.hs:45:1:parse error possibly incorrect indentation or mismatched brackets

It's a program that you give 3 numbers and it needs to order them crescently, I also created the function three that multiplies numbers by 3. That's what I tried to do:
ordertriple :: (Integer, Integer, Integer) -> (Integer, Integer, Integer)
ordertriple (x, y, z)
| x < y && x < z && y < z = (three x, three y, three z)
| x < y && x < z && z < y = (three x, three z, three y)
| y < x && y < z && x < z = (three y, three x, three z)
| y < x && y < z && z < x = (three y, three z, three x)
| z < x && z < y && y < x = (three z, three x, three y)
| otherwise = (three z, three y, three x)
you are missing the (..) around Integer, Integer, Integer and x,y,z:
orderTriple :: (Integer, Integer, Integer) -> (Integer, Integer, Integer)
orderTriple (x, y, z)
| x < y && x < z && y < z = (three x, three y, three z)
| x < y && x < z && z < y = (three x, three z, three y)
| y < x && y < z && x < z = (three y, three x, three z)
| y < x && y < z && z < x = (three y, three z, three x)
| z < x && z < y && y < x = (three z, three x, three y)
| otherwise = (three z, three y, three x
should work
Your code runs fine for me but you'll get more reuse out of something like this:
orderedTriple :: (Num a, Ord a) => (a, a, a) -> (a, a, a)
orderedTriple = mapTriplet (* 3) . orderedTriplet
mapTriplet :: (a -> b) -> (a, a, a) -> (b, b, b)
mapTriplet f (x, y, z) = (f x, f y, f z)
orderedTriplet :: Ord a => (a, a, a) -> (a, a, a)
orderedTriplet (x, y, z)
| x <= u = (x, u, v)
| x <= v = (u, x, v)
| otherwise = (u, v, x)
where (u, v) = orderedPair (y, z)
orderedPair :: Ord a => (a, a) -> (a, a)
orderedPair (x, y)
| x <= y = (x, y)
| otherwise = (y, x)
Ordering things and multiplying them by three are completely independent operations. Write a function to order them without multiplying them by three.
Can you see how to do this using at most three comparisons?
As for your parse error, run GHC with -fwarn-tabs. If it warns you about tabs, use spaces instead.

Is a train in J associative

In programming language J, is a train of verbs always associative? If it is, Are there any proofs?
No, a train of verbs is not associative and this follows the definitions. For example, a fork is
(f g h) y = (f y) g (h y)
but
(f (g h)) y = y f ((g h) y) = y f (y g (h y))
which can also be written as y f y g h y. And
((f g) h) y = y (f g) (h y) = y f (g (h y))
which can also be written as y f g h y.
Those three are completely different things.
Train in J is right associative, and the minimum group is a fork. Only when it cannot make a fork, it makes a hook. So
vvvvv = (vv(vvv)),
And
vvvv= (v(vvv)).

Resources