mirror of
https://github.com/Z3Prover/z3
synced 2025-04-13 12:28:44 +00:00
An initial update to support polymorphism from SMTLIB3 and the API (so far C, Python). The WIP SMTLIB3 format is assumed to be supporting the following declaration ``` (declare-type-var A) ``` Whenever A is used in a type signature of a function/constant or bound quantified variable, it is taken to mean that all instantiations of A are included in the signature and assertions. For example, if the function f is declared with signature A -> A, then there is a version of f for all instances of A. The semantics of polymorphism appears to follow previous proposals: the instances are effectively different functions. This may clash with some other notions, such as the type signature forall 'a . 'a -> 'a would be inhabited by a unique function (the identity), while this is not enforced in this version (and hopefully never because it is more busy work). The C API has the function 'Z3_mk_type_variable' to create a type variable and applying functions modulo polymorphic type signatures is possible. The kind Z3_TYPE_VAR is added to sort discriminators. This version is considered as early alpha. It passes a first rudimentary unit test involving quantified axioms, declare-fun, define-fun, and define-fun-rec.
106 lines
3.1 KiB
C++
106 lines
3.1 KiB
C++
/*++
|
|
Copyright (c) 2023 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
theory_polymorphism.h
|
|
|
|
Abstract:
|
|
|
|
Plugin for handling polymorphism
|
|
The plugin instantiates polymorphic axioms based on occurrences of polymorphic functions in other axioms.
|
|
It uses blocking literals to restart search when there are new axioms that can be instantiated.
|
|
|
|
Author:
|
|
|
|
Nikolaj Bjorner (nbjorner) 2013-07-11
|
|
|
|
--*/
|
|
#pragma once
|
|
|
|
#include "ast/polymorphism_inst.h"
|
|
#include "smt/smt_theory.h"
|
|
|
|
namespace smt {
|
|
|
|
class theory_polymorphism : public theory {
|
|
trail_stack m_trail;
|
|
polymorphism::inst m_inst;
|
|
expr_ref m_assumption;
|
|
unsigned m_qhead = 0;
|
|
bool m_pending = true;
|
|
|
|
bool internalize_atom(app*, bool) override { return false; }
|
|
bool internalize_term(app*) override { return false; }
|
|
void new_eq_eh(theory_var, theory_var) override { }
|
|
void new_diseq_eh(theory_var, theory_var) override {}
|
|
theory* mk_fresh(context* new_ctx) override { return alloc(theory_polymorphism, *new_ctx); }
|
|
char const * get_name() const override { return "polymorphism"; }
|
|
void display(std::ostream& out) const override {}
|
|
|
|
void push_scope_eh() override {
|
|
m_trail.push_scope();
|
|
}
|
|
|
|
void pop_scope_eh(unsigned n) override {
|
|
m_trail.pop_scope(n);
|
|
}
|
|
|
|
bool can_propagate() override {
|
|
return m_pending;
|
|
}
|
|
|
|
/**
|
|
* Assert instances of polymorphic axioms
|
|
*/
|
|
void propagate() override {
|
|
if (!m_pending)
|
|
return;
|
|
m_pending = false;
|
|
vector<polymorphism::instantiation> instances;
|
|
m_inst.instantiate(instances);
|
|
if (instances.empty())
|
|
return;
|
|
for (auto const& [orig, inst, sub] : instances)
|
|
ctx.add_asserted(inst);
|
|
ctx.internalize_assertions();
|
|
}
|
|
|
|
final_check_status final_check_eh() override {
|
|
if (m_inst.pending())
|
|
ctx.assign(~mk_literal(m_assumption), nullptr);
|
|
return FC_DONE;
|
|
}
|
|
|
|
void add_theory_assumptions(expr_ref_vector & assumptions) override {
|
|
if (m_qhead == ctx.get_num_asserted_formulas())
|
|
return;
|
|
m_assumption = m.mk_fresh_const("poly", m.mk_bool_sort());
|
|
assumptions.push_back(m_assumption);
|
|
ctx.push_trail(value_trail(m_qhead));
|
|
for (; m_qhead < ctx.get_num_asserted_formulas(); ++m_qhead)
|
|
m_inst.add(ctx.get_asserted_formula(m_qhead));
|
|
m_pending = true;
|
|
}
|
|
|
|
bool should_research(expr_ref_vector & assumptions) override {
|
|
for (auto * a : assumptions)
|
|
if (a == m_assumption)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
|
|
public:
|
|
theory_polymorphism(context& ctx):
|
|
theory(ctx, poly_family_id),
|
|
m_inst(ctx.get_manager(), m_trail),
|
|
m_assumption(ctx.get_manager()) {}
|
|
|
|
void init_model(model_generator & mg) override { }
|
|
};
|
|
|
|
};
|
|
|
|
|