///| Draft proposals are immutable token paths. Keeping the proposal separate
///| from a model provider makes the verifier usable with simulations, traces,
///|
/// and real inference backends.
pub enum DraftError {
EmptyProposal
TokenOutOfRange(Int)
InvalidDistribution(Int)
LengthMismatch
} derive(Eq, Debug)
///|
pub struct DraftToken {
token : Int
distribution : Array[Double]
}
///|
pub struct DraftProposal {
prefix : Array[Int]
tokens : Array[DraftToken]
}
///|
pub fn DraftProposal::length(self : DraftProposal) -> Int {
self.tokens.length()
}
///|
pub fn DraftProposal::proposed_tokens(self : DraftProposal) -> Array[Int] {
let output : Array[Int] = []
for item in self.tokens {
output.push(item.token)
}
output
}
///|
pub fn DraftProposal::full_path(self : DraftProposal) -> Array[Int] {
let output : Array[Int] = []
for token in self.prefix {
output.push(token)
}
for item in self.tokens {
output.push(item.token)
}
output
}
///|
fn distribution_is_valid(values : Array[Double]) -> Bool {
if values.length() == 0 {
return false
}
let mut total = 0.0
for value in values {
if !finite_number(value) || value < 0.0 || value > 1.0 {
return false
}
total = total + value
}
(total - 1.0).abs() < 0.000000001
}
///|
pub fn validate_proposal(proposal : DraftProposal) -> Result[Unit, DraftError] {
if proposal.tokens.length() == 0 {
return Err(EmptyProposal)
}
for item in proposal.tokens {
if !distribution_is_valid(item.distribution) {
return Err(InvalidDistribution(item.token))
}
if item.token < 0 || item.token >= item.distribution.length() {
return Err(TokenOutOfRange(item.token))
}
if item.distribution[item.token] <= 0.0 ||
item.distribution.length() != proposal.tokens[0].distribution.length() {
return Err(InvalidDistribution(item.token))
}
}
Ok(())
}
///|
pub fn make_proposal(
prefix : Array[Int],
tokens : Array[Int],
distributions : Array[Array[Double]],
) -> Result[DraftProposal, DraftError] {
if tokens.length() == 0 {
return Err(EmptyProposal)
}
if tokens.length() != distributions.length() {
return Err(LengthMismatch)
}
let items : Array[DraftToken] = []
for index in 0.. Ok(proposal)
Err(error) => Err(error)
}
}