1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
# Copyright (c) 1997-2024
# Ewgenij Gawrilow, Michael Joswig, and the polymake team
# Technische Universität Berlin, Germany
# https://polymake.org
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version: http://www.gnu.org/licenses/gpl.txt.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#-------------------------------------------------------------------------------
# @topic category core/functions/Schemas
# Functions for creating and manipulating JSON schemas describing serialized polymake objects.
package Polymake::User;
# @category Schemas
# Load a JSON schema from a file.
# @param [complete file] String filename
# @return Schema
user_function load_schema($) {
my ($filename) = @_;
replace_special_paths($filename);
load Schema($filename);
}
# @category Schemas
# Save a JSON schema in a file.
# @param Schema schema, e.g. created by [[create_permissive_schema]] or [[create_restrictive_schema]]
# @param [complete file] String filename file to store the JSON representation of the schema
# @option Bool canonical store JSON with pretty indentation and all properties ordered alphabetically.
# This is particularly useful if you are going to modify the schema in a text editor.
user_function save_schema(Schema,$; { canonical => false}) {
my ($schema, $filename, @options) = @_;
length($filename) > 0 or croak( "filename missing" );
replace_special_paths($filename);
$schema->save($filename, @options);
}
# @category Schemas
# Generate a JSON schema for one or more `big' object types
#
# The resulting schema will prescribe the representation of all known properties
# of the given big object types and allow arbitrary additional properties.
#
# @param Any object ... a big object or a type expression
# @return Schema
#
# @example [notest] create a schema for Polytope<Rational> and use it for validation of JSON input
# > $schema = create_permissive_schema(typeof Polytope<Rational>);
# > $schema->validate(decode_json($json_input_string));
# @example [application graph] create a schema for a representative big data object
# > $g = graph::complete(4);
# > $schema = create_permissive_schema($g);
user_function create_permissive_schema($@) {
Core::Serializer::create_permissive_schema(map {
my $type = instanceof Core::BigObject($_) ? $_->type : $_;
if (ref($type) ne "Polymake::Core::BigObjectType" || $type->abstract) {
croak( "Schemas::create_permissive - wrong argument ", ref($_) || "'$_'", ": only standalone big object types or instances allowed" );
}
$type
} @_);
}
# @category Schemas
# Generate a JSON schema from a given `big' object instance
#
# The resulting schema will exactly match the given object: it will declare all present properties
# as mandatory and not allow any other properties even if they are defined for the object type in general.
#
# Such a schema can be used for manipulating properties of other objects when they are serialized
# before storing in a file or a database.
#
# @param Any object
# @return Schema
#
# @example [application polytope] create a schema exactly describing a cross polytope
# > $c = polytope::cross(3);
# > $schema = create_restrictive_schema($c);
user_function create_restrictive_schema(Core::BigObject) {
&Core::Serializer::create_restrictive_schema;
}
package Polymake::Schema;
# Change the stored data type for properties in a restrictive schema
#
# Selected properties will be coerced to a different type when the object is stored in a data file
# or in PolyDB using this schema.
#
# Note: This function does not try to verify that the properties can be serialized as the given type
# or will be successfully deserialized when reading the object from a file or retrieving it from a database.
# It's solely in the users responsibility to choose a compatible and convertible data type.
#
# @param [complete Core::Property::InSchema] Any properties list of pairs ''PROPERTY_NAME => type''
# A property in a subobject is written in dotted path notation: ''"NAME1.NAME2.NAME3..."''
# Types can be specified by name in a string or as a ''typeof'' expression or as a type of an exsiting data object.
# Specifying ''undef'' or ''"default"'' will enforce storing the properties in their original form, as declared in the rulebase.
# This operation might be useful e.g. to update the schema after a data mode change.
# @example [notest] Require FACETS to be stored as a sparse matrix
# > $schema->prescribe_property_types(FACETS => typeof SparseMatrix<Rational>);
# @example [notest] Require F_VECTOR and F2_VECTOR to be stored with simple integer entries
# > $schema->prescribe_property_types(F_VECTOR => "Vector<Int>", F2_VECTOR => "Matrix<Int>");
# @example [notest] Require VERTICES to be stored as declared in the rules, that is, as a dense matrix
# > $schema->prescribe_property_types(VERTICES => "default");
user_method prescribe_property_types($@) {
if (@_ > 2 && @_ % 2) {
&Core::Serializer::prescribe_property_types;
} else {
croak( 'expecting pairs PROPERTY_NAME => TYPE' );
}
}
# Local Variables:
# mode: perl
# cperl-indent-level:3
# indent-tabs-mode:nil
# End:
|