// Souffle - A Datalog Compiler
// Copyright (c) 2017, The Souffle Developers. All rights reserved
// Licensed under the Universal Permissive License v 1.0 as shown at:
// - https://opensource.org/licenses/UPL
// - <souffle root>/licenses/SOUFFLE-UPL.txt

// Find pairs of amicable numbers up to a limit
// A pair of numbers are amicable if the sum of their factors add up to each other

// Build search range
.decl num(x : number)
num(1).
num(x+1) :- num(x), x < l, lim(l).

// Search limit
.decl lim(n : number)
.input lim

// Find factors of x excluding itself
.decl factor(x : number, f : number)
factor(x, f) :- num(x), num(f), f <= x / 2, x % f = 0.

// Compute the sum of all the factors of x
.decl factor_sum(x : number, fs : number)
factor_sum(x, f) :- num(x), f = sum i : factor(x, i).

// Find pairs of numbers whose factors add up to each other
.decl amicable(a : number, b : number)
.output amicable()
amicable(a, b) :- factor_sum(a, b), factor_sum(b, a), a < b.
