def check_activation(modal_implication, valuation): """ :param modal_implication: see active_modalities above :param valuation: see active_modalities above :return tuple representing modal implications (modal atom, classical atom) if modality is active. otherwise, return False. """ assert len( modal_implication.disjuncts ) <= 2, "The modal disjunction is not formed correctly: %s" % modal_implication prop_atom, modal_atom = None, None true_literals = valuation[0] false_literals = valuation[1] # given assertion there should be one prop atom and one modal atom for disjunct in modal_implication.disjuncts: if not is_complex(disjunct): prop_atom = disjunct elif my_isinstance(disjunct[0], Modality): modal_atom = disjunct # check valuation of prop_atom, to determine num_modal_atoms activity # check if prop_atom is negated if is_atomic(prop_atom) and str(prop_atom) not in true_literals: # not negated return modal_atom, prop_atom if not is_atomic(prop_atom) and str(prop_atom[1]) not in false_literals: return modal_atom, prop_atom return False
def deactivate_modalities(active_modal_set, valuation): """ :param active_modal_set: set of active modal implications (modal atom, classical atom) :return list of modal implications that remain active, after trying to deactivate by satisfying antecedent. """ active_modal = set() s = Optimize() # add current valuation to solver s.add((And(set(Bool(lit) for lit in valuation[0])))) s.add((And(set(Not(Bool(lit)) for lit in valuation[1])))) for imp_modalities in active_modal_set: s.add_soft(And(get_bool(imp_modalities[1])), 1) s.check() valuation = process_model(s.model()) for imp_modalities in active_modal_set: prop_ante = imp_modalities[1] if is_atomic(prop_ante) and (prop_ante not in valuation[0]): active_modal.add(imp_modalities) if not is_atomic(prop_ante) and prop_ante[1] not in valuation[1]: active_modal.add(imp_modalities) return active_modal
def get_bool(atom): """ :param atom: parsed classical atom, can be negated :return z3 appropriate boolean value """ assert not is_complex(atom), "Error adding atom to sat solver: %s" % atom # need to account for 'False' and 'True' if is_atomic(atom): if atom == TOP: return True elif atom == BOTTOM: return False else: return Bool(str(atom)) elif str(atom[0]) == '~': if atom[1] == TOP: return False elif atom[1] == BOTTOM: return True else: return Not(Bool(str(atom[1]))) else: # error sys.stderr.write('Error adding atom to sat solver: ' + str(atom) + '\n') raise SystemExit(1)
def get_tuple(atom): """ if atom is negated or modal returns tuple representation """ if u.is_atomic(atom): return atom else: return atom[0], get_tuple(atom[1])
def get_str(fml): """ Returns string for unary operators in correct syntactic form """ if u.is_atomic(fml): return str(fml) else: unary_connective = fml[0] if repr(unary_connective) == '~': return '~' + get_str(fml[1]) elif repr(unary_connective) == 'box': return '[' + unary_connective.id + ']' + get_str(fml[1]) elif repr(unary_connective) == 'dia': return '<' + unary_connective.id + '>' + get_str(fml[1])
def get_mc(fml, modal_context): """ Returns a tuple, specifically the modal context (MC) and remaining expression. Note, MC is a possibly empty sequence of universal box-like modal operators. """ if not u.is_atomic(fml): connective = repr(fml[0]) if connective == 'box': modal_context.append(fml[0]) return get_mc(fml[1], modal_context) else: return [modal_context, fml] else: return [modal_context, fml]
def wedge(self, other): r""" Compute the exterior product with another differential form. INPUT: - ``other``: another differential form OUTPUT: - the exterior product self/\\other. EXAMPLES: Exterior product of two 1-forms on a 3-dimensional manifold:: sage: m = Manifold(3, 'M') sage: c_xyz.<x,y,z> = m.chart('x y z', 'coord_xyz') sage: a = OneForm(m, 'A') sage: a[:] = (x, y, z) sage: b = OneForm(m, 'B') sage: b[2] = z^2 sage: a.view() ; b.view() A = x dx + y dy + z dz B = z^2 dz sage: h = a.wedge(b) ; h 2-form 'A/\B' on the 3-dimensional manifold 'M' sage: h.view() A/\B = x*z^2 dx/\dz + y*z^2 dy/\dz sage: latex(h) A\wedge B sage: latex(h.view()) A\wedge B = x z^{2} \mathrm{d} x\wedge\mathrm{d} z + y z^{2} \mathrm{d} y\wedge\mathrm{d} z The exterior product of two 1-forms is antisymmetric:: sage: (b.wedge(a)).view() B/\A = -x*z^2 dx/\dz - y*z^2 dy/\dz sage: a.wedge(b) == - b.wedge(a) True sage: (a.wedge(b) + b.wedge(a))[:] # for the skeptical mind [0 0 0] [0 0 0] [0 0 0] sage: a.wedge(a) == 0 True The exterior product of a 2-form by a 1-form:: sage: c = OneForm(m, 'C') sage: c[1] = y^3 ; c.view() C = y^3 dy sage: g = h.wedge(c) ; g 3-form 'A/\B/\C' on the 3-dimensional manifold 'M' sage: g.view() A/\B/\C = -x*y^3*z^2 dx/\dy/\dz sage: g[:] [[[0, 0, 0], [0, 0, -x*y^3*z^2], [0, x*y^3*z^2, 0]], [[0, 0, x*y^3*z^2], [0, 0, 0], [-x*y^3*z^2, 0, 0]], [[0, -x*y^3*z^2, 0], [x*y^3*z^2, 0, 0], [0, 0, 0]]] The exterior product of a 2-form by a 1-form is symmetric:: sage: h.wedge(c) == c.wedge(h) True """ from utilities import is_atomic if not isinstance(other, DiffForm): raise TypeError("The second argument for the exterior product " + "must be a differential form.") if other.rank == 0: return other*self if self.rank == 0: return self*other frame_name = self.common_frame(other) if frame_name is None: raise ValueError("No common frame for the exterior product.") rank_r = self.rank + other.rank cmp_s = self.components[frame_name] cmp_o = other.components[frame_name] cmp_r = CompFullyAntiSym(self.domain.frames[frame_name], rank_r) for ind_s, val_s in cmp_s._comp.items(): for ind_o, val_o in cmp_o._comp.items(): ind_r = ind_s + ind_o if len(ind_r) == len(set(ind_r)): # all indices are different cmp_r[ind_r] += val_s * val_o result = DiffForm(self.domain, rank_r) result.components[frame_name] = cmp_r if self.name is not None and other.name is not None: sname = self.name oname = other.name if not is_atomic(sname): sname = '(' + sname + ')' if not is_atomic(oname): oname = '(' + oname + ')' result.name = sname + '/\\' + oname if self.latex_name is not None and other.latex_name is not None: slname = self.latex_name olname = other.latex_name if not is_atomic(slname): slname = '(' + slname + ')' if not is_atomic(olname): olname = '(' + olname + ')' result.latex_name = slname + r'\wedge ' + olname return result
def view(self, frame_name=None, chart_name=None): r""" Displays the differential form in terms of its expansion onto a given coframe. The output is either text-formatted (console mode) or LaTeX-formatted (notebook mode). INPUT: - ``frame_name`` -- (default: None) string containing the name of the vector frame with respect to which the differential form is expanded; if none is provided, the domain's default frame is assumed - ``chart_name`` -- (default: None) string containing the name of the chart with respect to which the components of the differential form in the selected frame are expressed; if none is provided, the domain's default chart is assumed EXAMPLES: Display of a 2-form on `\RR^3`:: sage: m = Manifold(3, 'R3', '\RR^3', start_index=1) sage: c_cart.<x,y,z> = m.chart('x y z', 'cart') sage: a = DiffForm(m, 2, 'A') sage: a[1,2], a[2,3] = x*z, x^2+y^2 sage: a.view() # expansion on the manifold's default coframe (dx, dy, dz) A = x*z dx/\dy + (x^2 + y^2) dy/\dz sage: latex(a.view()) # output for the notebook A = x z \mathrm{d} x\wedge\mathrm{d} y + \left( x^{2} + y^{2} \right) \mathrm{d} y\wedge\mathrm{d} z Display in a coframe different from the default one:: sage: c_spher.<r,th,ph> = m.chart(r'r:[0,+oo) th:[0,pi]:\theta ph:[0,2*pi):\phi', 'spher') # new coordinates sage: spher_to_cart = CoordChange(c_spher, c_cart, r*sin(th)*cos(ph), r*sin(th)*sin(ph), r*cos(th)) # the standard spherical coordinates sage: cart_to_spher = spher_to_cart.set_inverse(sqrt(x^2+y^2+z^2), atan2(sqrt(x^2+y^2),z), atan2(y, x), check=False) sage: a.view('spher_b') # expansion on the coframe (dr, dth, dph) with the coefficients expressed in terms of the default coordinates (x,y,z) A = -sqrt(x^2 + y^2 + z^2)*sqrt(x^2 + y^2)*y dr/\dth + (x^3 + x*y^2 + x*z^2)*sqrt(x^2 + y^2) dth/\dph sage: a.view('spher_b', 'spher') # expansion on the coframe (dr, dth, dph) with the coefficients expressed in terms of the spherical coordinates A = -r^3*sin(ph)*sin(th)^2 dr/\dth + r^4*cos(ph)*sin(th)^2 dth/\dph """ from sage.misc.latex import latex from utilities import is_atomic, FormattedExpansion if frame_name is None: frame_name = self.domain.def_frame.name if chart_name is None: chart_name = self.domain.def_chart.name frame = self.domain.frames[frame_name] coframe = frame.coframe comp = self.comp(frame_name) terms_txt = [] terms_latex = [] n_con = self.tensor_type[0] for ind in comp.non_redundant_index_generator(): coef = comp[[ind]].expr(chart_name) if coef != 0: bases_txt = [] bases_latex = [] for k in range(self.rank): bases_txt.append(coframe(ind[k]).name) bases_latex.append(latex(coframe(ind[k]))) basis_term_txt = "/\\".join(bases_txt) basis_term_latex = r"\wedge".join(bases_latex) if coef == 1: terms_txt.append(basis_term_txt) terms_latex.append(basis_term_latex) elif coef == -1: terms_txt.append("-" + basis_term_txt) terms_latex.append("-" + basis_term_latex) else: coef_txt = repr(coef) coef_latex = latex(coef) if is_atomic(coef_txt): terms_txt.append(coef_txt + " " + basis_term_txt) else: terms_txt.append("(" + coef_txt + ") " + basis_term_txt) if is_atomic(coef_latex): terms_latex.append(coef_latex + basis_term_latex) else: terms_latex.append(r"\left(" + coef_latex + r"\right)" + basis_term_latex) if terms_txt == []: expansion_txt = "0" else: expansion_txt = terms_txt[0] for term in terms_txt[1:]: if term[0] == "-": expansion_txt += " - " + term[1:] else: expansion_txt += " + " + term if terms_latex == []: expansion_latex = "0" else: expansion_latex = terms_latex[0] for term in terms_latex[1:]: if term[0] == "-": expansion_latex += term else: expansion_latex += "+" + term result = FormattedExpansion(self) if self.name is None: result.txt = expansion_txt else: result.txt = self.name + " = " + expansion_txt if self.latex_name is None: result.latex = expansion_latex else: result.latex = latex(self) + " = " + expansion_latex return result
def wedge(self, other): r""" Compute the exterior product with another differential form. INPUT: - ``other``: another differential form OUTPUT: - the exterior product self/\\other. EXAMPLES: Exterior product of two 1-forms on a 3-dimensional manifold:: sage: m = Manifold(3, 'M') sage: c_xyz = Chart(m, 'x y z', 'coord_xyz') sage: a = OneForm(m, 'A') sage: a[:] = (x, y, z) sage: b = OneForm(m, 'B') sage: b[2] = z^2 sage: a.show() ; b.show() A = x dx + y dy + z dz B = z^2 dz sage: h = a.wedge(b) ; h 2-form 'A/\B' on the 3-dimensional manifold 'M' sage: h.show() A/\B = x*z^2 dx/\dz + y*z^2 dy/\dz sage: latex(h) A\wedge B sage: latex(h.show()) A\wedge B = x z^{2} \mathrm{d} x\wedge\mathrm{d} z + y z^{2} \mathrm{d} y\wedge\mathrm{d} z The exterior product of two 1-forms is antisymmetric:: sage: (b.wedge(a)).show() B/\A = -x*z^2 dx/\dz - y*z^2 dy/\dz sage: a.wedge(b) == - b.wedge(a) True sage: (a.wedge(b) + b.wedge(a))[:] # for the skeptical mind [0 0 0] [0 0 0] [0 0 0] sage: a.wedge(a) == 0 True The exterior product of a 2-form by a 1-form:: sage: c = OneForm(m, 'C') sage: c[1] = y^3 ; c.show() C = y^3 dy sage: g = h.wedge(c) ; g 3-form 'A/\B/\C' on the 3-dimensional manifold 'M' sage: g.show() A/\B/\C = -x*y^3*z^2 dx/\dy/\dz sage: g[:] [[[0, 0, 0], [0, 0, -x*y^3*z^2], [0, x*y^3*z^2, 0]], [[0, 0, x*y^3*z^2], [0, 0, 0], [-x*y^3*z^2, 0, 0]], [[0, -x*y^3*z^2, 0], [x*y^3*z^2, 0, 0], [0, 0, 0]]] The exterior product of a 2-form by a 1-form is symmetric:: sage: h.wedge(c) == c.wedge(h) True """ from utilities import is_atomic if not isinstance(other, DiffForm): raise TypeError("The second argument for the exterior product " + "must be a differential form.") if other.rank == 0: return other * self if self.rank == 0: return self * other frame_name = self.common_frame(other) if frame_name is None: raise ValueError("No common frame for the exterior product.") rank_r = self.rank + other.rank cmp_s = self.components[frame_name] cmp_o = other.components[frame_name] cmp_r = CompFullyAntiSym(self.manifold, rank_r, frame_name) for ind_s, val_s in cmp_s._comp.items(): for ind_o, val_o in cmp_o._comp.items(): ind_r = ind_s + ind_o if len(ind_r) == len(set(ind_r)): # all indices are different cmp_r[ind_r] += val_s * val_o result = DiffForm(self.manifold, rank_r) result.components[frame_name] = cmp_r if self.name is not None and other.name is not None: sname = self.name oname = other.name if not is_atomic(sname): sname = '(' + sname + ')' if not is_atomic(oname): oname = '(' + oname + ')' result.name = sname + '/\\' + oname if self.latex_name is not None and other.latex_name is not None: slname = self.latex_name olname = other.latex_name if not is_atomic(slname): slname = '(' + slname + ')' if not is_atomic(olname): olname = '(' + olname + ')' result.latex_name = slname + r'\wedge ' + olname return result
def show(self, frame_name=None, chart_name=None): r""" Displays the differential form in terms of its expansion onto a given coframe. The output is either text-formatted (console mode) or LaTeX-formatted (notebook mode). INPUT: - ``frame_name`` -- (default: None) string containing the name of the vector frame with respect to which the differential form is expanded; if none is provided, the manifold's default frame is assumed - ``chart_name`` -- (default: None) string containing the name of the chart with respect to which the components of the differential form in the selected frame are expressed; if none is provided, the manifold's default chart is assumed EXAMPLES: Display of a 2-form on `\RR^3`:: sage: m = Manifold(3, 'R3', '\RR^3', start_index=1) sage: c_cart = Chart(m, 'x y z', 'cart') sage: a = DiffForm(m, 2, 'A') sage: a[1,2], a[2,3] = x*z, x^2+y^2 sage: a.show() # expansion on the manifold's default coframe (dx, dy, dz) A = x*z dx/\dy + (x^2 + y^2) dy/\dz sage: latex(a.show()) # output for the notebook A = x z \mathrm{d} x\wedge\mathrm{d} y + \left( x^{2} + y^{2} \right) \mathrm{d} y\wedge\mathrm{d} z Display in a coframe different from the default one:: sage: c_spher = Chart(m, r'r:positive th:positive:\theta ph:\phi', 'spher') # new coordinates sage: spher_to_cart = CoordChange(c_spher, c_cart, r*sin(th)*cos(ph), r*sin(th)*sin(ph), r*cos(th)) # the standard spherical coordinates sage: cart_to_spher = spher_to_cart.set_inverse(sqrt(x^2+y^2+z^2), atan2(sqrt(x^2+y^2),z), atan2(y, x), check=False) sage: a.show('spher_b') # expansion on the coframe (dr, dth, dph) with the coefficients expressed in terms of the default coordinates (x,y,z) A = -sqrt(x^2 + y^2)*sqrt(x^2 + y^2 + z^2)*y dr/\dth + sqrt(x^2 + y^2)*(x^3 + x*y^2 + x*z^2) dth/\dph sage: a.show('spher_b', 'spher') # expansion on the coframe (dr, dth, dph) with the coefficients expressed in terms of the spherical coordinates A = -r^3*sin(ph)*sin(th)^2 dr/\dth + r^4*sin(th)^2*cos(ph) dth/\dph """ from sage.misc.latex import latex from utilities import is_atomic, FormattedExpansion if frame_name is None: frame_name = self.manifold.def_frame.name if chart_name is None: chart_name = self.manifold.def_chart.name frame = self.manifold.frames[frame_name] coframe = frame.coframe comp = self.comp(frame_name) terms_txt = [] terms_latex = [] n_con = self.tensor_type[0] for ind in comp.non_redundant_index_generator(): coef = comp[[ind]].expr(chart_name) if coef != 0: bases_txt = [] bases_latex = [] for k in range(self.rank): bases_txt.append(coframe(ind[k]).name) bases_latex.append(latex(coframe(ind[k]))) basis_term_txt = "/\\".join(bases_txt) basis_term_latex = r"\wedge".join(bases_latex) if coef == 1: terms_txt.append(basis_term_txt) terms_latex.append(basis_term_latex) elif coef == -1: terms_txt.append("-" + basis_term_txt) terms_latex.append("-" + basis_term_latex) else: coef_txt = repr(coef) coef_latex = latex(coef) if is_atomic(coef_txt): terms_txt.append(coef_txt + " " + basis_term_txt) else: terms_txt.append("(" + coef_txt + ") " + basis_term_txt) if is_atomic(coef_latex): terms_latex.append(coef_latex + basis_term_latex) else: terms_latex.append(r"\left(" + coef_latex + r"\right)" + basis_term_latex) if terms_txt == []: expansion_txt = "0" else: expansion_txt = terms_txt[0] for term in terms_txt[1:]: if term[0] == "-": expansion_txt += " - " + term[1:] else: expansion_txt += " + " + term if terms_latex == []: expansion_latex = "0" else: expansion_latex = terms_latex[0] for term in terms_latex[1:]: if term[0] == "-": expansion_latex += term else: expansion_latex += "+" + term result = FormattedExpansion(self) if self.name is None: result.txt = expansion_txt else: result.txt = self.name + " = " + expansion_txt if self.latex_name is None: result.latex = expansion_latex else: result.latex = latex(self) + " = " + expansion_latex return result