2019-11-02 02:13:45 +01:00
|
|
|
pub trait DisplayTPTP<'a, DisplayType>
|
|
|
|
where DisplayType: 'a + std::fmt::Debug + std::fmt::Display
|
|
|
|
{
|
|
|
|
fn display_tptp(&'a self) -> DisplayType;
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
pub fn is_formula_statement_axiom(formula_statement: &crate::project::FormulaStatement,
|
2019-11-07 05:42:42 +01:00
|
|
|
proof_direction: crate::project::ProofDirection) -> bool
|
2019-11-06 19:52:08 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
if formula_statement.proven
|
2019-11-07 07:53:50 +01:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
match (proof_direction, &formula_statement.kind)
|
2019-11-07 07:53:50 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
(_, crate::project::FormulaStatementKind::Axiom) => true,
|
|
|
|
(_, crate::project::FormulaStatementKind::Assumption) => true,
|
|
|
|
(crate::project::ProofDirection::Forward, crate::project::FormulaStatementKind::Completion(_)) => true,
|
|
|
|
(crate::project::ProofDirection::Backward, crate::project::FormulaStatementKind::Assertion) => true,
|
2019-11-07 07:53:50 +01:00
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
pub fn is_formula_statement_lemma(formula_statement: &crate::project::FormulaStatement,
|
2019-11-07 07:53:50 +01:00
|
|
|
proof_direction: crate::project::ProofDirection) -> bool
|
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
if formula_statement.proven
|
2019-11-07 07:53:50 +01:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
match (proof_direction, &formula_statement.kind)
|
2019-11-06 19:52:08 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
(_, crate::project::FormulaStatementKind::Lemma(None)) => true,
|
|
|
|
(proof_direction, crate::project::FormulaStatementKind::Lemma(Some(proof_direction_lemma))) => proof_direction == *proof_direction_lemma,
|
2019-11-07 04:20:06 +01:00
|
|
|
_ => false,
|
2019-11-06 19:52:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
pub fn is_formula_statement_theorem(formula_statement: &crate::project::FormulaStatement,
|
2019-11-07 07:53:50 +01:00
|
|
|
proof_direction: crate::project::ProofDirection) -> bool
|
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
if formula_statement.proven
|
2019-11-07 07:53:50 +01:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
match (proof_direction, &formula_statement.kind)
|
2019-11-07 07:53:50 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
(crate::project::ProofDirection::Forward, crate::project::FormulaStatementKind::Assertion) => true,
|
|
|
|
(crate::project::ProofDirection::Backward, crate::project::FormulaStatementKind::Completion(_)) => true,
|
2019-11-07 07:53:50 +01:00
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:26:56 +01:00
|
|
|
fn is_arithmetic_term(term: &foliage::Term) -> bool
|
|
|
|
{
|
|
|
|
match term
|
|
|
|
{
|
|
|
|
foliage::Term::Infimum => false,
|
|
|
|
foliage::Term::Supremum => false,
|
|
|
|
foliage::Term::Integer(_) => true,
|
|
|
|
foliage::Term::Symbolic(_) => false,
|
|
|
|
foliage::Term::String(_) => false,
|
|
|
|
foliage::Term::Variable(ref declaration) => match declaration.domain
|
|
|
|
{
|
|
|
|
foliage::Domain::Program => false,
|
|
|
|
foliage::Domain::Integer => true,
|
|
|
|
},
|
|
|
|
foliage::Term::Add(ref left, ref right) => is_arithmetic_term(left) && is_arithmetic_term(right),
|
|
|
|
foliage::Term::Subtract(ref left, ref right) => is_arithmetic_term(left) && is_arithmetic_term(right),
|
|
|
|
foliage::Term::Multiply(ref left, ref right) => is_arithmetic_term(left) && is_arithmetic_term(right),
|
|
|
|
foliage::Term::Negative(ref argument) => is_arithmetic_term(argument),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:50:46 +01:00
|
|
|
fn collect_predicate_declarations_in_formula<'a>(
|
|
|
|
predicate_declarations: &mut std::collections::HashSet<&'a foliage::PredicateDeclaration>, formula: &'a foliage::Formula)
|
|
|
|
{
|
|
|
|
match formula
|
|
|
|
{
|
|
|
|
foliage::Formula::Exists(ref exists) => collect_predicate_declarations_in_formula(predicate_declarations, &exists.argument),
|
|
|
|
foliage::Formula::ForAll(ref for_all) => collect_predicate_declarations_in_formula(predicate_declarations, &for_all.argument),
|
|
|
|
foliage::Formula::Not(ref argument) => collect_predicate_declarations_in_formula(predicate_declarations, argument),
|
|
|
|
foliage::Formula::And(ref arguments) =>
|
|
|
|
for argument in arguments
|
|
|
|
{
|
|
|
|
collect_predicate_declarations_in_formula(predicate_declarations, argument);
|
|
|
|
},
|
|
|
|
foliage::Formula::Or(ref arguments) =>
|
|
|
|
for argument in arguments
|
|
|
|
{
|
|
|
|
collect_predicate_declarations_in_formula(predicate_declarations, argument);
|
|
|
|
},
|
2019-11-07 02:05:04 +01:00
|
|
|
foliage::Formula::Implies(ref left, ref right, _) =>
|
2019-11-02 02:50:46 +01:00
|
|
|
{
|
|
|
|
collect_predicate_declarations_in_formula(predicate_declarations, left);
|
|
|
|
collect_predicate_declarations_in_formula(predicate_declarations, right);
|
|
|
|
},
|
|
|
|
foliage::Formula::Biconditional(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_predicate_declarations_in_formula(predicate_declarations, left);
|
|
|
|
collect_predicate_declarations_in_formula(predicate_declarations, right);
|
|
|
|
},
|
|
|
|
foliage::Formula::Less(_, _) => (),
|
|
|
|
foliage::Formula::LessOrEqual(_, _) => (),
|
|
|
|
foliage::Formula::Greater(_, _) => (),
|
|
|
|
foliage::Formula::GreaterOrEqual(_, _) => (),
|
|
|
|
foliage::Formula::Equal(_, _) => (),
|
|
|
|
foliage::Formula::NotEqual(_, _) => (),
|
|
|
|
foliage::Formula::Boolean(_) => (),
|
|
|
|
foliage::Formula::Predicate(ref predicate) =>
|
|
|
|
{
|
|
|
|
predicate_declarations.insert(&predicate.declaration);
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn collect_predicate_declarations_in_project<'a>(project: &'a crate::Project)
|
|
|
|
-> std::collections::HashSet<&'a foliage::PredicateDeclaration>
|
|
|
|
{
|
|
|
|
let mut predicate_declarations = std::collections::HashSet::new();
|
|
|
|
|
2019-11-05 19:44:28 +01:00
|
|
|
let formulas = project.blocks.iter()
|
|
|
|
.filter_map(
|
|
|
|
|block|
|
|
|
|
match block
|
|
|
|
{
|
|
|
|
crate::project::Block::Whitespace(_) => None,
|
2019-11-07 08:12:26 +01:00
|
|
|
crate::project::Block::FormulaStatement(ref formula_statement) => Some(&formula_statement.formula),
|
2019-11-05 19:44:28 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
for formula in formulas
|
2019-11-02 02:50:46 +01:00
|
|
|
{
|
2019-11-05 19:44:28 +01:00
|
|
|
collect_predicate_declarations_in_formula(&mut predicate_declarations, formula);
|
2019-11-02 02:50:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
predicate_declarations
|
|
|
|
}
|
|
|
|
|
2019-11-02 04:13:00 +01:00
|
|
|
fn collect_symbolic_constants_in_term<'a>(
|
|
|
|
symbolic_constants: &mut std::collections::HashSet<&'a str>, term: &'a foliage::Term)
|
|
|
|
{
|
|
|
|
match term
|
|
|
|
{
|
|
|
|
foliage::Term::Infimum => (),
|
|
|
|
foliage::Term::Supremum => (),
|
|
|
|
foliage::Term::Integer(_) => (),
|
|
|
|
foliage::Term::Symbolic(ref name) =>
|
|
|
|
{
|
|
|
|
symbolic_constants.insert(name);
|
|
|
|
},
|
|
|
|
foliage::Term::String(_) => (),
|
|
|
|
foliage::Term::Variable(_) => (),
|
|
|
|
foliage::Term::Add(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Term::Subtract(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Term::Multiply(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Term::Negative(ref argument) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, argument);
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn collect_symbolic_constants_in_formula<'a>(
|
|
|
|
symbolic_constants: &mut std::collections::HashSet<&'a str>, formula: &'a foliage::Formula)
|
|
|
|
{
|
|
|
|
match formula
|
|
|
|
{
|
|
|
|
foliage::Formula::Exists(ref exists) => collect_symbolic_constants_in_formula(symbolic_constants, &exists.argument),
|
|
|
|
foliage::Formula::ForAll(ref for_all) => collect_symbolic_constants_in_formula(symbolic_constants, &for_all.argument),
|
|
|
|
foliage::Formula::Not(ref argument) => collect_symbolic_constants_in_formula(symbolic_constants, argument),
|
|
|
|
foliage::Formula::And(ref arguments) =>
|
|
|
|
for argument in arguments
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_formula(symbolic_constants, argument);
|
|
|
|
},
|
|
|
|
foliage::Formula::Or(ref arguments) =>
|
|
|
|
for argument in arguments
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_formula(symbolic_constants, argument);
|
|
|
|
},
|
2019-11-07 02:05:04 +01:00
|
|
|
foliage::Formula::Implies(ref left, ref right, _) =>
|
2019-11-02 04:13:00 +01:00
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_formula(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_formula(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Formula::Biconditional(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_formula(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_formula(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Formula::Less(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Formula::LessOrEqual(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Formula::Greater(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Formula::GreaterOrEqual(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Formula::Equal(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Formula::NotEqual(ref left, ref right) =>
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, left);
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, right);
|
|
|
|
},
|
|
|
|
foliage::Formula::Boolean(_) => (),
|
|
|
|
foliage::Formula::Predicate(ref predicate) =>
|
|
|
|
{
|
|
|
|
for argument in &predicate.arguments
|
|
|
|
{
|
|
|
|
collect_symbolic_constants_in_term(symbolic_constants, &argument);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn collect_symbolic_constants_in_project<'a>(project: &'a crate::Project)
|
|
|
|
-> std::collections::HashSet<&'a str>
|
|
|
|
{
|
|
|
|
let mut symbolic_constants = std::collections::HashSet::new();
|
|
|
|
|
2019-11-05 19:44:28 +01:00
|
|
|
// TODO: avoid code duplication
|
|
|
|
let formulas = project.blocks.iter()
|
|
|
|
.filter_map(
|
|
|
|
|block|
|
|
|
|
match block
|
|
|
|
{
|
|
|
|
crate::project::Block::Whitespace(_) => None,
|
2019-11-07 08:12:26 +01:00
|
|
|
crate::project::Block::FormulaStatement(ref formula_statement) => Some(&formula_statement.formula),
|
2019-11-05 19:44:28 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
for formula in formulas
|
2019-11-02 04:13:00 +01:00
|
|
|
{
|
2019-11-05 19:44:28 +01:00
|
|
|
collect_symbolic_constants_in_formula(&mut symbolic_constants, formula);
|
2019-11-02 04:13:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
symbolic_constants
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:13:45 +01:00
|
|
|
struct VariableDeclarationDisplay<'a>(&'a foliage::VariableDeclaration);
|
2019-11-02 02:50:46 +01:00
|
|
|
struct PredicateDeclarationDisplay<'a>(&'a foliage::PredicateDeclaration);
|
2019-11-02 02:13:45 +01:00
|
|
|
struct TermDisplay<'a>(&'a foliage::Term);
|
|
|
|
struct FormulaDisplay<'a>(&'a foliage::Formula);
|
2019-11-07 08:12:26 +01:00
|
|
|
struct FormulaStatementDisplay<'a>
|
2019-11-06 19:52:08 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
formula_statement: &'a crate::project::FormulaStatement,
|
2019-11-07 05:42:42 +01:00
|
|
|
proof_direction: crate::project::ProofDirection,
|
2019-11-06 19:52:08 +01:00
|
|
|
}
|
2019-11-06 11:36:51 +01:00
|
|
|
pub struct ProjectDisplay<'a>
|
2019-11-02 07:23:34 +01:00
|
|
|
{
|
2019-11-06 11:36:51 +01:00
|
|
|
project: &'a crate::project::Project,
|
2019-11-07 08:12:26 +01:00
|
|
|
conjecture: &'a crate::project::FormulaStatement,
|
2019-11-07 05:42:42 +01:00
|
|
|
proof_direction: crate::project::ProofDirection,
|
2019-11-02 07:23:34 +01:00
|
|
|
}
|
2019-11-02 02:13:45 +01:00
|
|
|
|
|
|
|
impl<'a> DisplayTPTP<'a, VariableDeclarationDisplay<'a>> for foliage::VariableDeclaration
|
|
|
|
{
|
|
|
|
fn display_tptp(&'a self) -> VariableDeclarationDisplay<'a>
|
|
|
|
{
|
|
|
|
VariableDeclarationDisplay(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:50:46 +01:00
|
|
|
impl<'a> DisplayTPTP<'a, PredicateDeclarationDisplay<'a>> for foliage::PredicateDeclaration
|
|
|
|
{
|
|
|
|
fn display_tptp(&'a self) -> PredicateDeclarationDisplay<'a>
|
|
|
|
{
|
|
|
|
PredicateDeclarationDisplay(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:13:45 +01:00
|
|
|
impl<'a> DisplayTPTP<'a, TermDisplay<'a>> for foliage::Term
|
|
|
|
{
|
|
|
|
fn display_tptp(&'a self) -> TermDisplay<'a>
|
|
|
|
{
|
|
|
|
TermDisplay(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> DisplayTPTP<'a, FormulaDisplay<'a>> for foliage::Formula
|
|
|
|
{
|
|
|
|
fn display_tptp(&'a self) -> FormulaDisplay<'a>
|
|
|
|
{
|
|
|
|
FormulaDisplay(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
fn display_formula_statement_tptp<'a>(formula_statement: &'a crate::project::FormulaStatement,
|
2019-11-07 05:42:42 +01:00
|
|
|
proof_direction: crate::project::ProofDirection)
|
2019-11-07 08:12:26 +01:00
|
|
|
-> FormulaStatementDisplay<'a>
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
FormulaStatementDisplay
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
formula_statement,
|
2019-11-06 19:52:08 +01:00
|
|
|
proof_direction,
|
2019-11-02 02:13:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-06 11:36:51 +01:00
|
|
|
pub fn display_project_with_conjecture_tptp<'a>(project: &'a crate::Project,
|
2019-11-07 08:12:26 +01:00
|
|
|
conjecture: &'a crate::project::FormulaStatement, proof_direction: crate::project::ProofDirection)
|
2019-11-06 19:52:08 +01:00
|
|
|
-> ProjectDisplay<'a>
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
2019-11-02 07:23:34 +01:00
|
|
|
ProjectDisplay
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
2019-11-02 07:23:34 +01:00
|
|
|
project,
|
|
|
|
conjecture,
|
2019-11-06 19:52:08 +01:00
|
|
|
proof_direction,
|
2019-11-02 02:13:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> std::fmt::Debug for VariableDeclarationDisplay<'a>
|
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
|
|
|
match &self.0.domain
|
|
|
|
{
|
2019-11-05 20:58:21 +01:00
|
|
|
foliage::Domain::Program => write!(format, "{}: object", self.0.name),
|
|
|
|
foliage::Domain::Integer => write!(format, "{}: $int", self.0.name),
|
2019-11-02 02:13:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> std::fmt::Display for VariableDeclarationDisplay<'a>
|
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
|
|
|
write!(format, "{:?}", &self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:50:46 +01:00
|
|
|
impl<'a> std::fmt::Debug for PredicateDeclarationDisplay<'a>
|
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
|
|
|
write!(format, "{}: (", self.0.name)?;
|
|
|
|
|
|
|
|
let mut separator = "";
|
|
|
|
|
|
|
|
for _ in 0..self.0.arity
|
|
|
|
{
|
|
|
|
write!(format, "{}object", separator)?;
|
|
|
|
separator = " * "
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(format, ") > $o")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> std::fmt::Display for PredicateDeclarationDisplay<'a>
|
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
|
|
|
write!(format, "{:?}", &self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:13:45 +01:00
|
|
|
impl<'a> std::fmt::Debug for TermDisplay<'a>
|
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
|
|
|
match self.0
|
|
|
|
{
|
2019-11-02 07:54:29 +01:00
|
|
|
foliage::Term::Infimum => write!(format, "c__infimum__"),
|
|
|
|
foliage::Term::Supremum => write!(format, "c__supremum__"),
|
2019-11-02 02:13:45 +01:00
|
|
|
foliage::Term::Integer(value) => write!(format, "{}", value),
|
|
|
|
foliage::Term::Symbolic(ref value) => write!(format, "{}", value),
|
|
|
|
foliage::Term::String(ref value) => write!(format, "\"{}\"", value),
|
|
|
|
foliage::Term::Variable(ref declaration) => match declaration.domain
|
|
|
|
{
|
2019-11-05 20:58:21 +01:00
|
|
|
foliage::Domain::Program => write!(format, "{}", declaration.name),
|
|
|
|
foliage::Domain::Integer => write!(format, "{}", declaration.name),
|
2019-11-02 02:13:45 +01:00
|
|
|
},
|
|
|
|
foliage::Term::Add(ref left, ref right) => write!(format, "$sum({:?}, {:?})", (&**left).display_tptp(), right.display_tptp()),
|
2019-11-02 03:13:51 +01:00
|
|
|
foliage::Term::Subtract(ref left, ref right) => write!(format, "$difference({:?}, {:?})", left.display_tptp(), right.display_tptp()),
|
|
|
|
foliage::Term::Multiply(ref left, ref right) => write!(format, "$product({:?}, {:?})", left.display_tptp(), right.display_tptp()),
|
2019-11-02 02:13:45 +01:00
|
|
|
foliage::Term::Negative(ref argument) => write!(format, "$uminus({:?})", argument.display_tptp()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> std::fmt::Display for TermDisplay<'a>
|
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
|
|
|
write!(format, "{:?}", self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> std::fmt::Debug for FormulaDisplay<'a>
|
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
2019-11-02 02:26:56 +01:00
|
|
|
#[derive(Eq, PartialEq)]
|
|
|
|
enum Notation
|
|
|
|
{
|
|
|
|
Prefix,
|
|
|
|
Infix,
|
|
|
|
}
|
|
|
|
|
2019-11-02 04:13:00 +01:00
|
|
|
let mut display_comparison = |notation, operator_identifier: &str, operator_identifier_fallback, left, right| -> Result<(), std::fmt::Error>
|
2019-11-02 02:26:56 +01:00
|
|
|
{
|
2019-11-02 04:13:00 +01:00
|
|
|
write!(format, "(")?;
|
|
|
|
|
|
|
|
let mut notation = notation;
|
|
|
|
let mut operator_identifier = operator_identifier;
|
|
|
|
|
|
|
|
let left_is_arithmetic_term = is_arithmetic_term(left);
|
|
|
|
let right_is_arithmetic_term = is_arithmetic_term(right);
|
|
|
|
|
|
|
|
if let Some(operator_identifier_fallback) = operator_identifier_fallback
|
|
|
|
{
|
|
|
|
if !left_is_arithmetic_term || !right_is_arithmetic_term
|
|
|
|
{
|
|
|
|
notation = Notation::Prefix;
|
|
|
|
operator_identifier = operator_identifier_fallback;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:26:56 +01:00
|
|
|
if notation == Notation::Prefix
|
|
|
|
{
|
|
|
|
write!(format, "{}(", operator_identifier)?;
|
|
|
|
}
|
|
|
|
|
2019-11-02 04:13:00 +01:00
|
|
|
if left_is_arithmetic_term && !right_is_arithmetic_term
|
2019-11-02 02:26:56 +01:00
|
|
|
{
|
|
|
|
write!(format, "f__integer__({})", left.display_tptp())?;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
write!(format, "{}", left.display_tptp())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
match notation
|
|
|
|
{
|
|
|
|
Notation::Prefix => write!(format, ", ")?,
|
|
|
|
Notation::Infix => write!(format, " {} ", operator_identifier)?,
|
|
|
|
}
|
|
|
|
|
2019-11-02 04:13:00 +01:00
|
|
|
if right_is_arithmetic_term && !left_is_arithmetic_term
|
2019-11-02 02:26:56 +01:00
|
|
|
{
|
|
|
|
write!(format, "f__integer__({})", right.display_tptp())?;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
write!(format, "{}", right.display_tptp())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
if notation == Notation::Prefix
|
|
|
|
{
|
|
|
|
write!(format, ")")?;
|
|
|
|
}
|
|
|
|
|
2019-11-02 04:13:00 +01:00
|
|
|
write!(format, ")")
|
2019-11-02 02:26:56 +01:00
|
|
|
};
|
|
|
|
|
2019-11-02 02:13:45 +01:00
|
|
|
match self.0
|
|
|
|
{
|
|
|
|
foliage::Formula::Exists(ref exists) =>
|
|
|
|
{
|
|
|
|
write!(format, "?[")?;
|
|
|
|
|
|
|
|
let mut separator = "";
|
|
|
|
|
|
|
|
for parameter in &exists.parameters
|
|
|
|
{
|
|
|
|
write!(format, "{}{:?}", separator, parameter.display_tptp())?;
|
|
|
|
|
|
|
|
separator = ", "
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(format, "]: ({:?})", exists.argument.display_tptp())
|
|
|
|
},
|
|
|
|
foliage::Formula::ForAll(ref for_all) =>
|
|
|
|
{
|
|
|
|
write!(format, "![")?;
|
|
|
|
|
|
|
|
let mut separator = "";
|
|
|
|
|
|
|
|
for parameter in &for_all.parameters
|
|
|
|
{
|
|
|
|
write!(format, "{}{:?}", separator, parameter.display_tptp())?;
|
|
|
|
|
|
|
|
separator = ", "
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(format, "]: ({:?})", for_all.argument.display_tptp())
|
|
|
|
},
|
|
|
|
foliage::Formula::Not(ref argument) => write!(format, "~({:?})", argument.display_tptp()),
|
|
|
|
foliage::Formula::And(ref arguments) =>
|
|
|
|
{
|
2019-11-02 04:13:00 +01:00
|
|
|
write!(format, "(")?;
|
|
|
|
|
2019-11-02 02:13:45 +01:00
|
|
|
let mut separator = "";
|
|
|
|
|
|
|
|
for argument in arguments
|
|
|
|
{
|
|
|
|
write!(format, "{}{:?}", separator, argument.display_tptp())?;
|
|
|
|
|
|
|
|
separator = " & "
|
|
|
|
}
|
|
|
|
|
2019-11-02 04:13:00 +01:00
|
|
|
write!(format, ")")
|
2019-11-02 02:13:45 +01:00
|
|
|
},
|
|
|
|
foliage::Formula::Or(ref arguments) =>
|
|
|
|
{
|
2019-11-02 04:13:00 +01:00
|
|
|
write!(format, "(")?;
|
|
|
|
|
2019-11-02 02:13:45 +01:00
|
|
|
let mut separator = "";
|
|
|
|
|
|
|
|
for argument in arguments
|
|
|
|
{
|
|
|
|
write!(format, "{}{:?}", separator, argument.display_tptp())?;
|
|
|
|
|
|
|
|
separator = " | "
|
|
|
|
}
|
|
|
|
|
2019-11-02 04:13:00 +01:00
|
|
|
write!(format, ")")
|
2019-11-02 02:13:45 +01:00
|
|
|
},
|
2019-11-07 02:05:04 +01:00
|
|
|
foliage::Formula::Implies(ref left, ref right, implication_direction) => match implication_direction
|
|
|
|
{
|
|
|
|
foliage::ImplicationDirection::LeftToRight => write!(format, "({:?} => {:?})", left.display_tptp(), right.display_tptp()),
|
|
|
|
foliage::ImplicationDirection::RightToLeft => write!(format, "({:?} <= {:?})", left.display_tptp(), right.display_tptp()),
|
|
|
|
},
|
2019-11-02 02:13:45 +01:00
|
|
|
foliage::Formula::Biconditional(ref left, ref right) => write!(format, "({:?} <=> {:?})", left.display_tptp(), right.display_tptp()),
|
2019-11-02 04:13:00 +01:00
|
|
|
foliage::Formula::Less(ref left, ref right) => display_comparison(Notation::Prefix, "$less", Some("p__less__"), left, right),
|
|
|
|
foliage::Formula::LessOrEqual(ref left, ref right) => display_comparison(Notation::Prefix, "$lesseq", Some("p__less_equal__"), left, right),
|
|
|
|
foliage::Formula::Greater(ref left, ref right) => display_comparison(Notation::Prefix, "$greater", Some("p__greater__"), left, right),
|
|
|
|
foliage::Formula::GreaterOrEqual(ref left, ref right) => display_comparison(Notation::Prefix, "$greatereq", Some("p__greater_equal__"), left, right),
|
|
|
|
foliage::Formula::Equal(ref left, ref right) => display_comparison(Notation::Infix, "=", None, left, right),
|
2019-11-02 07:54:29 +01:00
|
|
|
foliage::Formula::NotEqual(ref left, ref right) => display_comparison(Notation::Infix, "!=", None, left, right),
|
2019-11-02 02:13:45 +01:00
|
|
|
foliage::Formula::Boolean(value) =>
|
|
|
|
match value
|
|
|
|
{
|
|
|
|
true => write!(format, "$true"),
|
|
|
|
false => write!(format, "$false"),
|
|
|
|
},
|
|
|
|
foliage::Formula::Predicate(ref predicate) =>
|
|
|
|
{
|
|
|
|
write!(format, "{}", predicate.declaration.name)?;
|
|
|
|
|
|
|
|
if !predicate.arguments.is_empty()
|
|
|
|
{
|
|
|
|
write!(format, "(")?;
|
|
|
|
|
|
|
|
let mut separator = "";
|
|
|
|
|
|
|
|
for argument in &predicate.arguments
|
|
|
|
{
|
2019-11-02 04:13:00 +01:00
|
|
|
let argument_is_arithmetic_term = is_arithmetic_term(argument);
|
|
|
|
|
2019-11-05 22:54:28 +01:00
|
|
|
write!(format, "{}", separator)?;
|
|
|
|
|
2019-11-02 04:13:00 +01:00
|
|
|
if argument_is_arithmetic_term
|
|
|
|
{
|
|
|
|
write!(format, "f__integer__(")?;
|
|
|
|
}
|
|
|
|
|
2019-11-05 22:54:28 +01:00
|
|
|
write!(format, "{:?}", argument.display_tptp())?;
|
2019-11-02 02:13:45 +01:00
|
|
|
|
2019-11-02 04:13:00 +01:00
|
|
|
if argument_is_arithmetic_term
|
|
|
|
{
|
|
|
|
write!(format, ")")?;
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:13:45 +01:00
|
|
|
separator = ", "
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(format, ")")?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> std::fmt::Display for FormulaDisplay<'a>
|
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
|
|
|
write!(format, "{:?}", self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
impl<'a> std::fmt::Debug for FormulaStatementDisplay<'a>
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
2019-11-07 07:53:50 +01:00
|
|
|
write!(format, "\ntff(")?;
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
let identifier = match &self.formula_statement.kind
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
crate::project::FormulaStatementKind::Axiom => "axiom",
|
|
|
|
crate::project::FormulaStatementKind::Assumption => "assumption",
|
|
|
|
crate::project::FormulaStatementKind::Completion(_) => "completion",
|
|
|
|
crate::project::FormulaStatementKind::Assertion => "assertion",
|
|
|
|
crate::project::FormulaStatementKind::Lemma(_) => "lemma",
|
2019-11-07 07:53:50 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
write!(format, "{}, ", identifier)?;
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
if is_formula_statement_theorem(&self.formula_statement, self.proof_direction)
|
|
|
|
|| is_formula_statement_lemma(&self.formula_statement, self.proof_direction)
|
2019-11-07 07:53:50 +01:00
|
|
|
{
|
|
|
|
write!(format, "conjecture")?;
|
|
|
|
}
|
2019-11-07 08:12:26 +01:00
|
|
|
else if is_formula_statement_axiom(&self.formula_statement, self.proof_direction)
|
2019-11-07 07:53:50 +01:00
|
|
|
{
|
|
|
|
write!(format, "axiom")?;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
panic!("expected formula statement to be either theorem, lemma, or axiom, please report to bug tracker");
|
2019-11-02 02:13:45 +01:00
|
|
|
}
|
2019-11-07 07:53:50 +01:00
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
write!(format, ", {:?}).", self.formula_statement.formula.display_tptp())
|
2019-11-02 02:13:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
impl<'a> std::fmt::Display for FormulaStatementDisplay<'a>
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
|
|
|
write!(format, "{:?}", &self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-06 11:36:51 +01:00
|
|
|
impl<'a> std::fmt::Debug for ProjectDisplay<'a>
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
2019-11-02 04:13:00 +01:00
|
|
|
let write_title = |format: &mut std::fmt::Formatter, line_separator, title_identifier|
|
|
|
|
{
|
|
|
|
write!(format, "{}{}", line_separator, "%".repeat(80))?;
|
|
|
|
write!(format, "\n% {}", title_identifier)?;
|
|
|
|
write!(format, "\n{}", "%".repeat(80))
|
|
|
|
};
|
|
|
|
|
|
|
|
write_title(format, "", "anthem types")?;
|
|
|
|
|
|
|
|
let tptp_preamble_anthem_types = include_str!("tptp_preamble_anthem_types.tptp").trim_end();
|
|
|
|
write!(format, "\n{}", tptp_preamble_anthem_types)?;
|
|
|
|
|
|
|
|
write_title(format, "\n\n", "anthem axioms")?;
|
|
|
|
|
|
|
|
let tptp_preamble_anthem_axioms = include_str!("tptp_preamble_anthem_axioms.tptp").trim_end();
|
|
|
|
write!(format, "\n{}", tptp_preamble_anthem_axioms)?;
|
2019-11-02 02:50:46 +01:00
|
|
|
|
2019-11-02 07:23:34 +01:00
|
|
|
let predicate_declarations = collect_predicate_declarations_in_project(self.project);
|
|
|
|
let symbolic_constants = collect_symbolic_constants_in_project(self.project);
|
2019-11-02 02:50:46 +01:00
|
|
|
|
2019-11-02 04:13:00 +01:00
|
|
|
if !predicate_declarations.is_empty() || !symbolic_constants.is_empty()
|
2019-11-02 02:50:46 +01:00
|
|
|
{
|
2019-11-02 04:13:00 +01:00
|
|
|
write_title(format, "\n\n", "types")?;
|
|
|
|
|
2019-11-02 02:50:46 +01:00
|
|
|
for predicate_declaration in predicate_declarations
|
|
|
|
{
|
|
|
|
write!(format, "\ntff(type, type, {:?}).", predicate_declaration.display_tptp())?;
|
|
|
|
}
|
2019-11-02 04:13:00 +01:00
|
|
|
|
|
|
|
for symbolic_constant in symbolic_constants
|
|
|
|
{
|
|
|
|
write!(format, "\ntff(type, type, {}: object).", symbolic_constant)?;
|
|
|
|
}
|
2019-11-02 02:50:46 +01:00
|
|
|
}
|
2019-11-02 02:13:45 +01:00
|
|
|
|
2019-11-05 19:44:28 +01:00
|
|
|
let axioms = self.project.blocks.iter()
|
|
|
|
.filter_map(
|
|
|
|
|block|
|
|
|
|
match block
|
|
|
|
{
|
|
|
|
crate::project::Block::Whitespace(_) => None,
|
2019-11-07 08:12:26 +01:00
|
|
|
crate::project::Block::FormulaStatement(ref formula_statement) =>
|
|
|
|
match is_formula_statement_axiom(&formula_statement, self.proof_direction)
|
2019-11-05 19:44:28 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
true => Some(formula_statement),
|
2019-11-07 07:53:50 +01:00
|
|
|
false => None,
|
2019-11-05 19:44:28 +01:00
|
|
|
}
|
|
|
|
});
|
2019-11-02 02:50:46 +01:00
|
|
|
|
2019-11-05 19:44:28 +01:00
|
|
|
for axiom in axioms
|
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
write!(format, "\n{}", display_formula_statement_tptp(&axiom, self.proof_direction))?;
|
2019-11-02 02:13:45 +01:00
|
|
|
}
|
|
|
|
|
2019-11-06 19:52:08 +01:00
|
|
|
write_title(format, "\n\n", "assertion")?;
|
2019-11-02 07:23:34 +01:00
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
write!(format, "\n{}", display_formula_statement_tptp(&self.conjecture, self.proof_direction))
|
2019-11-02 02:13:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-06 11:36:51 +01:00
|
|
|
impl<'a> std::fmt::Display for ProjectDisplay<'a>
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
|
|
|
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
|
|
|
|
{
|
|
|
|
write!(format, "{:?}", &self)
|
|
|
|
}
|
|
|
|
}
|