lean2/src/library/rewrite/fo_match.cpp

248 lines
6.6 KiB
C++
Raw Normal View History

/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Soonho Kong
*/
#include <utility>
#include "kernel/expr.h"
#include "kernel/context.h"
#include "library/all/all.h"
#include "library/arith/nat.h"
#include "library/arith/arith.h"
2013-09-19 19:21:29 +00:00
#include "library/rewrite/fo_match.h"
#include "library/rewrite/rewrite.h"
2013-09-19 19:21:29 +00:00
#include "library/printer.h"
2013-09-19 19:21:29 +00:00
using std::cout;
using std::endl;
2013-09-19 19:21:29 +00:00
namespace lean {
2013-09-19 19:21:29 +00:00
std::ostream & operator<<(std::ostream & out, subst_map & s) {
out << "{";
for (auto it = s.begin(); it != s.end(); it++) {
out << it->first << " => ";
out << it->second << "; ";
}
out << "}";
return out;
}
2013-09-19 19:21:29 +00:00
bool fo_match::match_var(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match_var : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
unsigned idx = var_idx(p);
if (idx < o) {
// Current variable is the one created by lambda inside of pattern
// and it is not a target of pattern matching.
return p == t;
} else {
2013-09-19 19:21:29 +00:00
auto it = s.find(p);
if (it != s.end()) {
// This variable already has an entry in the substitution
// map. We need to make sure that 't' and s[idx] are the
// same
cout << "match_var exist:" << p << " |-> " << it->second << endl;
return it->second == t;
}
// This variable has no entry in the substituition map. Let's
// add one.
s.insert(std::make_pair(p, t));
cout << "match_var MATCHED : " << s << endl;
return true;
}
}
2013-09-19 19:21:29 +00:00
bool fo_match::match_constant(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match_constant : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
return p == t;
}
bool fo_match::match_value(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match_value : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
return p == t;
}
bool fo_match::match_app(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match_app : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
unsigned num_p = num_args(p);
unsigned num_t = num_args(p);
if (num_p != num_t) {
return false;
}
2013-09-19 19:21:29 +00:00
for (unsigned i = 0; i < num_p; i++) {
if (!match(arg(p, i), arg(t, i), o, s))
return false;
}
return true;
}
2013-09-19 19:21:29 +00:00
bool fo_match::match_lambda(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match_lambda : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
cout << "fun (" << abst_name(p)
<< " : " << abst_domain(p)
<< "), " << abst_body(p) << endl;
if (!is_lambda(t)) {
return false;
2013-09-19 19:21:29 +00:00
} else {
// First match the domain part
auto p_domain = abst_domain(p);
auto t_domain = abst_domain(t);
if (!match(p_domain, t_domain, o, s))
return false;
2013-09-19 19:21:29 +00:00
// Then match the body part, increase offset by 1.
auto p_body = abst_body(p);
auto t_body = abst_body(t);
return match(p_domain, t_domain, o + 1, s);
}
}
2013-09-19 19:21:29 +00:00
bool fo_match::match_pi(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match_pi : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
cout << "Pi (" << abst_name(p)
<< " : " << abst_domain(p)
<< "), " << abst_body(p) << endl;
if (!is_pi(t)) {
return false;
} else {
// First match the domain part
auto p_domain = abst_domain(p);
auto t_domain = abst_domain(t);
if (!match(p_domain, t_domain, o, s))
return false;
// Then match the body part, increase offset by 1.
auto p_body = abst_body(p);
auto t_body = abst_body(t);
return match(p_domain, t_domain, o + 1, s);
}
}
2013-09-19 19:21:29 +00:00
bool fo_match::match_type(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match_type : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
return p == t;
}
2013-09-19 19:21:29 +00:00
bool fo_match::match_eq(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match_eq : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
return match(eq_lhs(p), eq_lhs(t), o, s) && match(eq_rhs(p), eq_rhs(t), o, s);
}
2013-09-19 19:21:29 +00:00
bool fo_match::match_let(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match_let : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
if (!is_let(t)) {
return false;
} else {
// First match the type part
auto p_type = let_type(p);
auto t_type = let_type(t);
if (!match(p_type, t_type, o, s))
return false;
// then match the value part
auto p_value = let_value(p);
auto t_value = let_value(t);
if (!match(p_value, t_value, o, s))
return false;
// then match the value part
auto p_body = let_body(p);
auto t_body = let_body(t);
return match(p_body, t_body, o + 1, s);
}
}
2013-09-19 19:21:29 +00:00
bool fo_match::match_metavar(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match_meta : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
return p == t;
}
2013-09-19 19:21:29 +00:00
bool fo_match::match(expr const & p, expr const & t, unsigned o, subst_map & s) {
cout << "match : ("
<< p << ", "
<< t << ", "
<< o << ", "
<< s << ")"
<< endl;
switch (p.kind()) {
case expr_kind::Var:
2013-09-19 19:21:29 +00:00
return match_var(p, t, o, s);
case expr_kind::Constant:
2013-09-19 19:21:29 +00:00
return match_constant(p, t, o, s);
case expr_kind::Value:
2013-09-19 19:21:29 +00:00
return match_value(p, t, o, s);
case expr_kind::App:
2013-09-19 19:21:29 +00:00
return match_app(p, t, o, s);
case expr_kind::Lambda:
2013-09-19 19:21:29 +00:00
return match_lambda(p, t, o, s);
case expr_kind::Pi:
2013-09-19 19:21:29 +00:00
return match_pi(p, t, o, s);
case expr_kind::Type:
2013-09-19 19:21:29 +00:00
return match_type(p, t, o, s);
case expr_kind::Eq:
2013-09-19 19:21:29 +00:00
return match_eq(p, t, o, s);
case expr_kind::Let:
2013-09-19 19:21:29 +00:00
return match_let(p, t, o, s);
case expr_kind::MetaVar:
2013-09-19 19:21:29 +00:00
return match_metavar(p, t, o, s);
}
2013-09-19 19:21:29 +00:00
lean_unreachable();
return false;
}
}