///|
fn log_text(value : Double) -> String {
if value == @double.neg_infinity {
"-inf"
} else {
value.to_string()
}
}
///|
/// Deterministic section/lexicographic order; numeric precision is not truncated.
pub fn Model::to_arpa(self : Model) -> String raise ArpaError {
let records = self.records()
records.sort_by((a, b) => {
let size = a.tokens.length().compare(b.tokens.length())
if size == 0 {
gram_key(a.tokens).compare(gram_key(b.tokens))
} else {
size
}
})
let lines = ["\\data\\"]
let counts = self.counts()
for i = 0; i < counts.length(); i = i + 1 {
lines.push("ngram \{i + 1}=\{counts[i]}")
}
let mut cursor = 0
let mut size = lines.join("\n").length()
for order = 1; order <= self.order; order = order + 1 {
let marker = "\n\\\{order}-grams:"
lines.push(marker)
size += marker.length() + 1
while cursor < records.length() && records[cursor].tokens.length() == order {
let record = records[cursor]
let row = log_text(record.log_probability) +
"\t" +
record.tokens.join(" ") +
(match record.log_backoff {
Some(b) => "\t" + log_text(b)
None => ""
})
if row.length() > self.limits.max_text - size {
raise Budget("ARPA output limit")
}
size += row.length() + 1
lines.push(row)
cursor += 1
}
}
lines.push("\n\\end\\\n")
let output = lines.join("\n")
if output.length() > self.limits.max_text {
raise Budget("ARPA output limit")
}
output
}