use crate::{
control::*,
entity::*,
inference::{
rules::{cast_statement, utils::*},
*,
},
language::*,
symbols::CONJUNCTION_OPERATOR,
};
use nar_dev_utils::{unwrap_or_return, RefCount};
use ReasonDirection::*;
pub fn deduction(
sub: Term,
pre: Term,
task: &impl Sentence,
belief: &impl Judgement,
context: &mut ReasonContextConcept,
) {
let content = unwrap_or_return!(
?Term::make_statement(task.content(), sub, pre)
);
let truth = match context.reason_direction() {
Forward => Some(task.unwrap_judgement().deduction(belief)),
Backward => None,
};
let budget = match context.reason_direction() {
Forward => context.budget_forward(truth.as_ref()),
Backward => context.budget_backward_weak(belief),
};
context.double_premise_task(content, truth, budget);
}
pub fn exemplification(
sub: Term,
pre: Term,
task: &impl Sentence,
belief: &impl Judgement,
context: &mut ReasonContextConcept,
) {
let content = unwrap_or_return!(
?Term::make_statement(task.content(), pre, sub)
);
let truth = match context.reason_direction() {
Forward => Some(task.unwrap_judgement().exemplification(belief)),
Backward => None,
};
let budget = match context.reason_direction() {
Forward => context.budget_forward(truth.as_ref()),
Backward => context.budget_backward_weak(belief),
};
context.double_premise_task(content, truth, budget);
}
pub fn abduction(
sub: Term,
pre: Term,
task: &impl Sentence,
belief: &impl Judgement,
context: &mut ReasonContextConcept,
) {
let content = unwrap_or_return!(
?Term::make_statement(task.content(), sub, pre)
);
let truth = match context.reason_direction() {
Forward => Some(task.unwrap_judgement().abduction(belief)),
Backward => None,
};
let budget = match context.reason_direction() {
Forward => context.budget_forward(truth.as_ref()),
Backward => context.budget_backward(belief),
};
context.double_premise_task(content, truth, budget);
}
pub fn induction(
sub: Term,
pre: Term,
task: &impl Sentence,
belief: &impl Judgement,
context: &mut ReasonContextConcept,
) {
let content = unwrap_or_return!(
?Term::make_statement(task.content(), pre, sub)
);
let truth = match context.reason_direction() {
Forward => Some(task.unwrap_judgement().induction(belief)),
Backward => None,
};
let budget = match context.reason_direction() {
Forward => context.budget_forward(truth.as_ref()),
Backward => context.budget_backward_weak(belief),
};
context.double_premise_task(content, truth, budget);
}
pub fn comparison(
sub: Term,
pre: Term,
task: &impl Sentence,
belief: &impl Judgement,
context: &mut ReasonContextConcept,
) {
let content = unwrap_or_return!(
?Term::make_statement_symmetric(task.content(), sub, pre)
);
let truth = match context.reason_direction() {
Forward => Some(task.unwrap_judgement().comparison(belief)),
Backward => None,
};
let budget = match context.reason_direction() {
Forward => context.budget_forward(truth.as_ref()),
Backward => context.budget_backward(belief),
};
context.double_premise_task(content, truth, budget);
}
pub fn analogy(
sub: Term,
pre: Term,
asymmetric: impl Sentence,
symmetric: impl Sentence,
context: &mut ReasonContextConcept,
) {
if StatementRef::invalid_statement(&sub, &pre) {
return;
}
let task_rc = context.current_task();
let task = task_rc.get_();
let direction = context.reason_direction();
let task_content = task.content();
let asymmetric_statement = asymmetric.content().as_statement().unwrap();
let content = unwrap_or_return!(?Term::make_statement(&asymmetric_statement, sub, pre));
let truth = match direction {
Forward => Some(
asymmetric
.unwrap_judgement()
.analogy(symmetric.unwrap_judgement()),
),
Backward => None,
};
let is_commutative = task_content.is_commutative();
drop(task);
drop(task_rc);
let budget = match direction {
Forward => context.budget_forward(truth.as_ref()),
Backward => {
match is_commutative {
true => context.budget_backward_weak(asymmetric.unwrap_judgement()),
false => context.budget_backward(symmetric.unwrap_judgement()),
}
}
};
context.double_premise_task(content, truth, budget);
}
pub fn conditional_abduction(
condition_t: &Term,
condition_b: &Term,
statement_t: &Statement,
statement_b: &Statement,
context: &mut ReasonContextConcept,
) -> bool {
if !statement_t.instanceof_implication() || !statement_b.instanceof_implication() {
return false;
}
let [conjunction_t, conjunction_b] = match [
condition_t.as_compound_type(CONJUNCTION_OPERATOR),
condition_b.as_compound_type(CONJUNCTION_OPERATOR),
] {
[None, None] => return false,
options => options,
};
let task_truth = context
.current_task()
.get_()
.as_judgement()
.map(TruthValue::from);
let belief_truth = TruthValue::from(unwrap_or_return!(
?context.current_belief() => false
));
let direction = context.reason_direction();
let reduced_t =
conjunction_t.and_then(|conjunction_t| conjunction_t.reduce_components(condition_b));
let reduced_b =
conjunction_b.and_then(|conjunction_b| conjunction_b.reduce_components(condition_t));
let mut derive = |other_statement,
[self_condition, other_condition]: [&Option<Term>; 2],
[self_truth, other_truth]: [&Option<TruthValue>; 2]| 'derive: {
let self_condition = unwrap_or_return! {
?self_condition => break 'derive false };
let content = match other_condition {
Some(other_condition) => unwrap_or_return!(
?Term::make_statement(other_statement, other_condition.clone(), self_condition.clone())
=> break 'derive false ),
None => self_condition.clone(),
};
let truth = match direction {
Forward => {
let [self_truth, other_truth] = [
unwrap_or_return!(?self_truth => break 'derive false),
unwrap_or_return!(?other_truth => break 'derive false),
];
Some(other_truth.abduction(self_truth))
}
Backward => None,
};
let budget = match direction {
Forward => context.budget_forward(truth.as_ref()),
Backward => context.budget_backward_weak(&belief_truth),
};
context.double_premise_task(content, truth, budget);
true
};
let [derived_t, derived_b] = [
derive(
statement_b,
[&reduced_t, &reduced_b],
[&task_truth, &Some(belief_truth)],
),
derive(
statement_t,
[&reduced_b, &reduced_t],
[&Some(belief_truth), &task_truth],
),
];
derived_t || derived_b
}
pub fn conditional_deduction_induction(
conditional: Statement,
index_in_condition: usize,
premise2: Term,
belief_truth: &impl Truth,
conditional_from: PremiseSource, side: SyllogismSide,
context: &mut ReasonContextConcept,
) {
use SyllogismSide::*;
let [rng_seed, rng_seed2, rng_seed3] = context.shuffle_rng_seeds();
let task_truth = context
.current_task()
.get_()
.as_judgement()
.map(TruthValue::from);
let [_, unified_belief_content] = conditional_from.select([&*conditional, &premise2]);
let conditional_task =
variable_process::has_unification_i(&premise2, unified_belief_content, rng_seed);
let direction = context.reason_direction();
let deduction = side != Subject;
let [common_component, new_component] = side.select_exclusive(&premise2);
let common_component = common_component.expect("应该有提取到");
let old_condition = unwrap_or_return!(
?conditional.get_ref().subject.as_compound_type(CONJUNCTION_OPERATOR)
);
let index_2 = old_condition.index_of_component(common_component);
let index_in_old_condition;
let conditional_unified; if let Some(index_2) = index_2 {
index_in_old_condition = index_2;
conditional_unified = conditional.clone();
} else {
index_in_old_condition = index_in_condition;
let condition_to_unify = unwrap_or_return!(
?old_condition.component_at(index_in_old_condition)
);
let unification_i =
variable_process::unify_find_i(condition_to_unify, common_component, rng_seed2);
if unification_i.has_unification {
let mut to_be_apply = conditional.clone();
unification_i
.unify_map_1
.apply_to(to_be_apply.mut_ref().into_compound_ref());
conditional_unified = to_be_apply;
} else if common_component.is_same_type(&old_condition) {
let common_component_component = unwrap_or_return!(
?common_component
.as_compound()
.unwrap()
.component_at(index_in_old_condition)
);
let unification_i = variable_process::unify_find_i(
condition_to_unify,
common_component_component,
rng_seed3,
);
if unification_i.has_unification {
let mut to_be_apply = conditional.clone();
unification_i
.unify_map_1
.apply_to(to_be_apply.mut_ref().into_compound_ref());
conditional_unified = to_be_apply;
} else {
return;
}
} else {
return;
}
}
let new_condition = match old_condition.inner == common_component {
true => None,
false => old_condition.set_component(index_in_old_condition, new_component.cloned()),
};
let (_, copula, predicate) = conditional_unified.unwrap();
let content = match new_condition {
Some(new_condition) => {
unwrap_or_return!(?Term::make_statement_relation(copula, new_condition, predicate))
}
None => predicate,
};
let truth = match direction {
Forward => Some(match deduction {
true => task_truth.unwrap().deduction(belief_truth),
false => match conditional_task {
true => belief_truth.induction(&task_truth.unwrap()),
false => task_truth.unwrap().induction(belief_truth),
},
}),
Backward => None,
};
let budget = match direction {
Forward => context.budget_forward(&truth.unwrap()),
Backward => context.budget_backward_weak(belief_truth),
};
context.double_premise_task(content, truth, budget);
}
pub fn conditional_analogy(
mut belief_equivalence: Statement, index_in_condition: usize,
mut task_implication: Statement, common_term_side: SyllogismSide,
belief_truth: &impl Truth,
context: &mut ReasonContextConcept,
) {
let [rng_seed1, rng_seed2, rng_seed3] = context.shuffle_rng_seeds();
let task_truth: Option<TruthValue> = context
.current_task()
.get_()
.as_judgement()
.map(TruthValue::from);
let direction = context.reason_direction();
let conditional_task =
variable_process::has_unification_i(&task_implication, &belief_equivalence, rng_seed1);
let [common_component, _] = common_term_side.select_exclusive(&task_implication);
let common_component = common_component.expect("应该有提取到");
let old_condition = unwrap_or_return!(
?belief_equivalence.get_ref().subject.as_compound_type(CONJUNCTION_OPERATOR)
);
let common_in_condition = old_condition.component_at(index_in_condition).unwrap();
let unification_d =
variable_process::unify_find_d(common_in_condition, common_component, rng_seed2);
let unification = if unification_d.has_unification {
unification_d
} else if common_component.is_same_type(&old_condition) {
let common_inner = common_component
.as_compound()
.unwrap()
.component_at(index_in_condition)
.unwrap();
let unification_d =
variable_process::unify_find_d(common_in_condition, common_inner, rng_seed3);
if unification_d.has_unification {
unification_d
} else {
return; }
} else {
return; };
unification.apply_to(
belief_equivalence.mut_ref().into_compound_ref(),
task_implication.mut_ref().into_compound_ref(),
);
let [common_component, new_component] = common_term_side.select_exclusive(&task_implication);
let common_component = common_component.expect("应该有提取到");
let old_condition = unwrap_or_return!(
?belief_equivalence.get_ref().subject.as_compound_type(CONJUNCTION_OPERATOR)
);
let new_condition = match *old_condition == *common_component {
true => None,
false => old_condition.set_component(index_in_condition, new_component.cloned()),
};
let (_, copula, premise1_predicate) = belief_equivalence.unwrap();
let content = match new_condition {
Some(new_condition) => unwrap_or_return!(
?Term::make_statement_relation(copula, new_condition, premise1_predicate)
),
None => premise1_predicate,
};
let truth = match direction {
Forward => Some(match conditional_task {
true => task_truth.unwrap().comparison(belief_truth),
false => task_truth.unwrap().analogy(belief_truth),
}),
Backward => None,
};
let budget = match direction {
Forward => context.budget_forward(&truth.unwrap()),
Backward => context.budget_backward_weak(belief_truth),
};
context.double_premise_task(content, truth, budget);
}
pub fn infer_to_sym(
judgement1: &impl Judgement,
judgement2: &impl Judgement,
context: &mut ReasonContextConcept,
) {
let [sub, pre] = cast_statement(judgement1.content().clone()).unwrap_components();
let content = unwrap_or_return!(
?Term::make_statement_symmetric(judgement1.content(), sub, pre)
);
let truth = judgement1.intersection(judgement2);
let budget = context.budget_forward(&truth);
context.double_premise_task(content, Some(truth), budget);
}
pub fn infer_to_asy(
asy: &impl Judgement,
sym: &impl Judgement,
context: &mut ReasonContextConcept,
) {
let [pre, sub] = cast_statement(asy.content().clone()).unwrap_components();
let content = unwrap_or_return!(
?Term::make_statement(asy.content(), sub, pre)
);
let truth = sym.reduce_conjunction(asy);
let budget = context.budget_forward(&truth);
context.double_premise_task(content, Some(truth), budget);
}
pub fn conversion(belief: &impl Judgement, context: &mut ReasonContextConcept) {
let truth = belief.conversion();
let budget = context.budget_forward(&truth);
converted_judgment(truth, budget, context);
}
pub fn convert_relation(task_question: &impl Question, context: &mut ReasonContextConcept) {
let belief = unwrap_or_return!(
?context.current_belief()
);
let truth = match task_question.content().is_commutative() {
true => belief.analytic_abduction(ShortFloat::ONE),
false => belief.analytic_deduction(ShortFloat::ONE),
};
let budget = context.budget_forward(&truth);
converted_judgment(truth, budget, context);
}
pub fn converted_judgment(
new_truth: TruthValue,
new_budget: BudgetValue,
context: &mut ReasonContextConcept,
) {
let task_content = cast_statement(context.current_task().get_().content().clone());
let belief_content = cast_statement(
context
.current_belief()
.expect("概念推理一定有当前信念")
.content()
.clone(),
);
let (sub_t, copula, pre_t) = task_content.unwrap();
let [sub_b, pre_b] = belief_content.unwrap_components();
let [sub, pre] = match [sub_t.contain_var_q(), pre_t.contain_var_q()] {
[_, true] => {
let eq_sub_t = sub_t == sub_b; [
sub_t,
match eq_sub_t {
true => pre_b,
false => sub_b,
},
]
}
[true, _] => [
match pre_t == sub_b {
true => pre_b,
false => sub_b,
},
pre_t,
],
_ => [sub_t, pre_t],
};
let content = unwrap_or_return!(?Term::make_statement_relation(copula, sub, pre));
context.single_premise_task_full(content, Punctuation::Judgement, Some(new_truth), new_budget)
}
pub fn resemblance(
sub: Term,
pre: Term,
belief: &impl Judgement,
task: &impl Sentence,
context: &mut ReasonContextConcept,
) {
if StatementRef::invalid_statement(&sub, &pre) {
return;
}
let direction = context.reason_direction();
let content = unwrap_or_return!(
?Term::make_statement(belief.content(), sub, pre)
);
let truth = match direction {
Forward => Some(belief.resemblance(task.unwrap_judgement())),
Backward => None,
};
let budget = match direction {
Forward => context.budget_forward(truth.as_ref()),
Backward => context.budget_backward(belief),
};
context.double_premise_task(content, truth, budget);
}
pub fn detachment(
task_sentence: &impl Sentence,
belief: &impl Judgement,
high_order_position: PremiseSource,
position_sub_in_hi: SyllogismPosition,
context: &mut ReasonContextConcept,
) {
let [high_order_statement, _] =
high_order_position.select([task_sentence.content(), belief.content()]); if !(high_order_statement.instanceof_implication()
|| high_order_statement.instanceof_equivalence())
{
return;
}
let high_order_statement = cast_statement(high_order_statement.clone());
let high_order_symmetric = high_order_statement.is_commutative(); let [sub, pre] = high_order_statement.unwrap_components();
let direction = context.reason_direction();
let [_, sub_content] = high_order_position.select([task_sentence.content(), belief.content()]); use SyllogismPosition::*;
let content = match position_sub_in_hi {
Subject if *sub_content == sub => pre,
Predicate if *sub_content == pre => sub,
_ => return,
};
if let Some(statement) = content.as_statement() {
if statement.invalid() {
return;
}
}
let truth = match direction {
Forward => {
let [main_sentence_truth, sub_sentence_truth] = high_order_position.select([
TruthValue::from(task_sentence.unwrap_judgement()),
TruthValue::from(belief),
]);
Some(match (high_order_symmetric, position_sub_in_hi) {
(true, _) => sub_sentence_truth.analogy(&main_sentence_truth),
(_, Subject) => main_sentence_truth.deduction(&sub_sentence_truth),
(_, Predicate) => sub_sentence_truth.abduction(&main_sentence_truth),
})
}
Backward => None,
};
let budget = match direction {
Forward => context.budget_forward(&truth.unwrap()), Backward => match (high_order_symmetric, position_sub_in_hi) {
(true, _) | (_, Predicate) => context.budget_backward(belief),
(_, Subject) => context.budget_backward_weak(belief),
},
};
context.double_premise_task(content, truth, budget);
}
#[cfg(test)]
mod tests {
use crate::expectation_tests;
expectation_tests! {
deduction: {
"
nse <A --> B>.
nse <B --> C>.
cyc 10
"
=> OUT "<A --> C>" in outputs
}
deduction_answer: {
"
nse <A --> B>.
nse <B --> C>.
nse <A --> C>?
cyc 50
"
=> ANSWER "<A --> C>" in outputs
}
deduction_backward: {
"
nse <A --> B>.
nse <?1 --> B>?
cyc 10
"
=> OUT "<?1 --> A>" in outputs
}
exemplification: {
"
nse <A --> B>.
nse <B --> C>.
cyc 10
"
=> OUT "<C --> A>" in outputs
}
exemplification_backward: {
"
nse <A --> B>.
nse <?1 --> B>?
cyc 10
"
=> OUT "<A --> ?1>" in outputs
}
exemplification_answer: {
"
nse <A --> B>.
nse <B --> C>.
nse <C --> A>?
cyc 20
"
=> ANSWER "<C --> A>" in outputs
}
abduction_sub: {
"
nse <A --> B>.
nse <A --> C>.
cyc 10
"
=> OUT "<B --> C>" in outputs
}
abduction_answer_sub: {
"
nse <A --> B>.
nse <A --> C>.
nse <B --> C>?
cyc 20
"
=> ANSWER "<B --> C>" in outputs
}
abduction_backward_sub: {
"
nse <A --> B>.
nse <A --> {?1}>?
cyc 20
"
=> OUT "<B --> {?1}>" in outputs
}
abduction_pre: {
"
nse <B --> A>.
nse <C --> A>.
cyc 10
"
=> OUT "<C --> B>" in outputs
}
abduction_answer_pre: {
"
nse <B --> A>.
nse <C --> A>.
nse <C --> B>?
cyc 20
"
=> ANSWER "<C --> B>" in outputs
}
induction_sub: {
"
nse <A --> B>.
nse <A --> C>.
cyc 10
"
=> OUT "<C --> B>" in outputs
}
induction_answer_sub: {
"
nse <A --> B>.
nse <A --> C>.
nse <C --> B>?
cyc 20
"
=> ANSWER "<C --> B>" in outputs
}
induction_pre: {
"
nse <B --> A>.
nse <C --> A>.
cyc 10
"
=> OUT "<B --> C>" in outputs
}
induction_answer_pre: {
"
nse <B --> A>.
nse <C --> A>.
nse <B --> C>?
cyc 20
"
=> ANSWER "<B --> C>" in outputs
}
comparison_sub: {
"
nse <A --> B>.
nse <A --> C>.
cyc 10
"
=> OUT "<B <-> C>" in outputs
}
comparison_answer_sub: {
"
nse <A --> B>.
nse <A --> C>.
nse <B <-> C>?
cyc 20
"
=> ANSWER "<B <-> C>" in outputs
}
comparison_pre: {
"
nse <B --> A>.
nse <C --> A>.
cyc 10
"
=> OUT "<B <-> C>" in outputs
}
comparison_answer_pre: {
"
nse <B --> A>.
nse <C --> A>.
nse <B <-> C>?
cyc 20
"
=> ANSWER "<B <-> C>" in outputs
}
analogy_sub: {
"
nse <A --> B>.
nse <C <-> A>.
cyc 10
"
=> OUT "<C --> B>" in outputs
}
analogy_answer_sub: {
"
nse <A --> B>.
nse <C <-> A>.
nse <C --> B>?
cyc 20
"
=> ANSWER "<C --> B>" in outputs
}
analogy_pre: {
"
nse <A --> B>.
nse <C <-> A>.
cyc 10
"
=> OUT "<C --> B>" in outputs
}
analogy_answer_pre: {
"
nse <A --> B>.
nse <C <-> A>.
nse <C --> B>?
cyc 20
"
=> ANSWER "<C --> B>" in outputs
}
conversion: {
"
nse <A --> B>.
nse <B --> A>?
cyc 10
"
=> ANSWER "<B --> A>" in outputs
}
infer_to_asy: {
"
nse <A <-> B>.
nse <A --> B>?
cyc 10
"
=> ANSWER "<A --> B>" in outputs
}
infer_to_sym: {
"
nse <A --> B>.
nse <A <-> B>?
cyc 10
"
=> ANSWER "<A <-> B>" in outputs
}
conversion_high: {
"
nse <A ==> B>.
nse <B ==> A>?
cyc 10
"
=> ANSWER "<B ==> A>" in outputs
}
infer_to_asy_high: {
"
nse <A <=> B>.
nse <A ==> B>?
cyc 10
"
=> ANSWER "<A ==> B>" in outputs
}
infer_to_sym_high: {
"
nse <A ==> B>.
nse <A <=> B>?
cyc 10
"
=> ANSWER "<A <=> B>" in outputs
}
resemblance: {
"
nse <A <-> B>.
nse <B <-> C>.
cyc 10
"
=> OUT "<A <-> C>" in outputs
}
resemblance_answer: {
"
nse <A <-> B>.
nse <B <-> C>.
nse <A <-> C>?
cyc 20
"
=> ANSWER "<A <-> C>" in outputs
}
detachment: {
"
nse <A ==> B>.
nse A.
cyc 10
"
=> OUT "B" in outputs
}
detachment_answer: {
"
nse <A ==> B>.
nse A.
nse B?
cyc 20
"
=> ANSWER "B" in outputs
}
detachment_weak: {
"
nse <A ==> B>.
nse B.
cyc 10
"
=> OUT "A" in outputs
}
detachment_answer_weak: {
"
nse <A ==> B>.
nse B.
nse A?
cyc 20
"
=> ANSWER "A" in outputs
}
detachment_var: {
"
nse <<$1 --> A> ==> <$1 --> B>>.
nse <C --> A>.
cyc 10
"
=> OUT "<C --> B>" in outputs
}
detachment_var_answer: {
"
nse <<$1 --> A> ==> <$1 --> B>>.
nse <C --> A>.
nse <C --> B>?
cyc 20
"
=> ANSWER "<C --> B>" in outputs
}
detachment_var_weak: {
"
nse <<$1 --> A> ==> <$1 --> B>>.
nse <C --> B>.
cyc 10
"
=> OUT "<C --> A>" in outputs
}
detachment_var_answer_weak: {
"
nse <<$1 --> A> ==> <$1 --> B>>.
nse <C --> B>.
nse <C --> A>?
cyc 20
"
=> ANSWER "<C --> A>" in outputs
}
conditional_abduction: {
"
nse <(&&, S2, S3) ==> P>.
nse <(&&, S1, S3) ==> P>.
cyc 10
"
=> OUT "<S1 ==> S2>" in outputs
}
conditional_abduction_answer: {
"
nse <(&&, S2, S3) ==> P>.
nse <(&&, S1, S3) ==> P>.
nse <S1 ==> S2>?
cyc 20
"
=> ANSWER "<S1 ==> S2>" in outputs
}
conditional_abduction_rev: {
"
nse <(&&, S2, S3) ==> P>.
nse <(&&, S1, S3) ==> P>.
cyc 10
"
=> OUT "<S2 ==> S1>" in outputs
}
conditional_abduction_rev_answer: {
"
nse <(&&, S2, S3) ==> P>.
nse <(&&, S1, S3) ==> P>.
nse <S2 ==> S1>?
cyc 20
"
=> ANSWER "<S2 ==> S1>" in outputs
}
conditional_deduction_reduce: {
"
nse <(&&, S1, S2, S3) ==> P>.
nse S1.
cyc 10
"
=> OUT "<(&&, S2, S3) ==> P>" in outputs
}
conditional_deduction_reduce_answer: {
"
nse <(&&, S1, S2, S3) ==> P>.
nse S1.
nse <(&&, S2, S3) ==> P>?
cyc 20
"
=> ANSWER "<(&&, S2, S3) ==> P>" in outputs
}
conditional_deduction_replace: {
"
nse <(&&, S2, S3) ==> P>.
nse <S1 ==> S2>.
cyc 100
"
=> OUT "<(&&, S1, S3) ==> P>" in outputs
}
conditional_deduction_replace_answer: {
"
nse <(&&, S2, S3) ==> P>.
nse <S1 ==> S2>.
nse <(&&, S1, S3) ==> P>?
cyc 200
"
=> ANSWER "<(&&, S1, S3) ==> P>" in outputs
}
conditional_induction: {
"
nse <(&&, S1, S3) ==> P>.
nse <S1 ==> S2>.
cyc 100
"
=> OUT "<(&&, S2, S3) ==> P>" in outputs
}
conditional_induction_answer: {
"
nse <(&&, S1, S3) ==> P>.
nse <S1 ==> S2>.
nse <(&&, S2, S3) ==> P>?
cyc 200
"
=> ANSWER "<(&&, S2, S3) ==> P>" in outputs
}
fail_case_image_from_image_from_conditional_ded: {
"
nse $0.80;0.80;0.95$ <(&&,<$x --> key>,<$y --> lock>) ==> <$y --> (/,open,$x,_)>>. %1.00;0.90%
nse $0.80;0.80;0.95$ <{lock1} --> lock>. %1.00;0.90%
cyc 40
"
=> OUT "<<$1 --> key> ==> <{lock1} --> (/,open,$1,_)>>" in outputs
}
}
}