// 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

.type Label <: number

.type NT <: symbol
.type Letter <: symbol
.type Symbol = NT | Letter

.type Pos <: number

// Head stored in position 0 of prod
.decl Prod				(x:Label, p:Pos, s:Symbol)
.decl String			(c:Pos, a:Letter)
.input Prod
.input String

.decl EndProd			(x:Label, p:Pos)
.decl EndString			(c:Pos)

.decl NotEndProd		(x:Label, p:Pos)
.decl NotEndString		(c:Pos)

NotEndProd(x, p) :- Prod(x, p, _), Prod(x, q, _), p < q.
EndProd(x, p + 1) :- Prod(x, p, _), !NotEndProd(x, p).

NotEndString(c) :- String(c, _), String(d, _), c < d.
EndString(c + 1) :- String(c, _), !NotEndString(c).

// Adapted from Earley parser - Wikipedia

// Current parse position in the string is c, production x has been matched
// up to position p in the body starting at position j in the input string.
.decl State			(c:Pos, x:Label, p:Pos, j:Pos)

// Initialization: at input position 1, production 1 has matched 0 symbols from origin 1.
State(1, 1, 1, 1).

// Prediction
State(c, x, 1, c) :- State(c, y, p, _), Prod(x, 0, n), Prod(y, p, n).

// Scanning
State(c + 1, x, p + 1, j) :- String(c, a), State(c, x, p, j), Prod(x, p, a).

// Completion
State(c, x, p + 1, j) :- State(c, y, q, k), EndProd(y, q), Prod(y, 0, n), State(k, x, p, j), Prod(x, p, n).

.type Answer <: symbol
.decl Accept			(s:Answer)

Accept("Yes") :- State(c, 1, q, 1), EndString(c), EndProd(1, q).
.output Accept
