# Pythagorean Triples
```elixir
Mix.install([
{:guesswork, "~> 0.5"},
{:kino, "~> 0.13"}
],
consolidate_protocols: false
)
```
## Queries that Calculate Values
```elixir
import Guesswork.Ast
alias Guesswork.Ast.And
alias Guesswork.Ast.Assign
alias Guesswork.Ast.OneOf
alias Guesswork.Answer.Result
alias Guesswork.Query
```
Queries don't necisarily need facts to operate (in fact, `Guesswork.query/2` will just
use an empty collection), they can use assigned values, and then calculate new values.
The below example is a really simple query that uses `Guesswork.Ast.Assign` to assign
values to `a` and `b`, and then uses `is` to calculated a third value based on the first two.
It should be noted that, in most cases, statements are created with functions.
But the `is` macro is needed to build a `Guesswork.Ast.Is`.
```elixir
Guesswork.query(
term(And.new([Assign.new(a, 1), Assign.new(b, 2), is(d, fn a, b -> b - a end)])),
10
)
```
Below is a more complex example, calculating pythagorean triples.
Instead of using `set` we use `one_of` to assign an enumerable to a variable, so that
the variable can be one of any of the values.
Then we use `is` again, but this time to test that our variables really are pythagorean
triples.
```elixir
Guesswork.query(
term(
And.new([
OneOf.new(a, 1..10),
OneOf.new(b, 1..10),
OneOf.new(c, 1..10),
is(true, fn a, b -> a < b end),
is(0, fn a, b, c -> Integer.pow(c, 2) - Integer.pow(a, 2) - Integer.pow(b, 2) end)
])
),
10
)
```
But `one_of` will support not just finite enumerables, but streams.
So below we calculate the first ten triples for all positive integers.
Its worth noting that here, instead of using just using the `query` function,
we create an unresolved query, and then run it.
This allows us to reuse the query below.
```elixir
query =
Query.new(
term(
And.new([
OneOf.new(a, Stream.iterate(1, &(&1 + 1))),
OneOf.new(b, Stream.iterate(1, &(&1 + 1))),
OneOf.new(c, Stream.iterate(1, &(&1 + 1))),
is(true, fn a, b -> a < b end),
is(0, fn a, b, c -> Integer.pow(c, 2) - Integer.pow(a, 2) - Integer.pow(b, 2) end)
])
)
)
Result.run(query, 10)
```
Now that we have the unresolved query we can calculate even more, and pull the first 100.
Note that this will take a few seconds.
The process is brute force, so as you request more results, more combinations of `a`,
`b`, and `c` will have to be tested.
```elixir
Result.run(query, 100)
```