예제 #1
0
    def make_instance(cls,
                      module,
                      metamodule=None,
                      semantics_module=None,
                      preds_module=None):
        """Make an instance of the semantics for the given problem"""

        # Use the default semantics and predicates module if not specified
        if semantics_module is None:
            semantics_module = cls.SEMANTICS_MODULE
        if preds_module is None:
            preds_module = cls.PREDS_MODULE

        # Load the opsem.maude file if not already done
        if maude.getModule(semantics_module) is None:
            with get_resource_path('opsem.maude') as templog_path:
                if not maude.load(str(templog_path)):
                    usermsgs.print_error(
                        'Error loading the small-step operational semantics'
                        'of the strategy language (opsem.maude).')
                    return None

        # Instantiate the semantics for the given module
        maude.input(
            cls.get_instantiation(module, metamodule, semantics_module,
                                  preds_module))
        osmod = maude.getCurrentModule()

        if osmod is None:
            usermsgs.print_error(
                'Error instantiating the small-step operational semantics.')
            return None

        return cls(osmod, module)
예제 #2
0
 def __init__(self):
     super().__init__('maude_listener')
     self.subscription = self.create_subscription(String, 'maude_msgs',
                                                  self.listener_callback,
                                                  10)
     self.subscription  # prevent unused variable warning
     self.maude_nat = maude.getModule('NAT')
예제 #3
0
def build_instance(filename,
                   initial_txt,
                   strategy_txt,
                   module_txt=None,
                   semantics_module='NOP-SEMANTICS'):
    """Build the model for the logic"""

    maude.load(filename)

    # Target module
    targetmod = maude.getCurrentModule(
    ) if module_txt is None else maude.getModule(module_txt)

    # Operational semantics module
    maude.input(
        INSTANTIATION.format(targetmod=targetmod,
                             semanticsmod=semantics_module))
    osmod = maude.getCurrentModule()

    # Create the helper class to handle the instance
    instance = OpSemInstance(osmod, targetmod)

    # Initial term
    initial_term = targetmod.parseTerm(initial_txt)

    if initial_term is None:
        sys.exit(1)

    initial_term.reduce()

    initial_metaterm = osmod.upTerm(initial_term)

    # Strategy expression
    strategy = targetmod.parseStrategy(strategy_txt)

    if strategy is None:
        sys.exit(1)

    strategy_metaterm = osmod.upStrategy(strategy)

    # Construct the terms in the semantics
    t = instance.stack_state(initial_metaterm, strategy_metaterm)

    return instance, t
예제 #4
0
 def __init__(self, module_name, sorts_names):
     self.module_name = module_name
     self.module = maude.getModule(module_name)
     self.sorts_names = sorts_names
     self.vcs = []
예제 #5
0
파일: api.py 프로젝트: fadoss/umaudemc
    def __init__(self,
                 initial,
                 strategy=None,
                 filename=None,
                 module=None,
                 metamodule=None,
                 opaque=(),
                 biased_matchrew=True,
                 already_loaded=False,
                 single_use=False):
        """
		Generate a Maude model for model-checking.

		:param initial: Initial term
		:type initial: str or maude.Term
		:param strategy: Strategy to control rewriting
		:type strategy: str or maude.StrategyExpression or None
		:param filename: Name of the file to be loaded
		:type filename: str or None
		:param module: Module where to model check
		:type module: str or maude.Module or None
		:param metamodule: Metarepresentation of the module where to model check
		(parsed in module)
		:type metamodule: str or maude.Term or None
		:param opaque: List of opaque strategies
		:type opaque: list of str
		:param biased_matchrew: Whether the biased matchrew feature is enabled
		:param biased_matchrew: bool
		:param already_loaded: Whether the file should not be loaded again
		:param already_loaded: bool
		:param single_use: Whether a single use of the model with the graph method
		is intended. Otherwise, graphs will be cached between calls to check
		:param single_use: bool
		"""

        # File name

        self.filename = filename
        needs_loading = not isinstance(module, maude.Module) \
                        and not isinstance(initial, maude.Term) \
                        and not already_loaded

        if needs_loading:
            if self.filename is None:
                raise ValueError(
                    'filename must not be empty if not already loaded')
            else:
                maude.load(self.filename)

        # Module

        if module is None:
            if isinstance(initial, maude.Term) and metamodule is None:
                self.module = initial.symbol().getModule()
            else:
                self.module = maude.getCurrentModule()
            self.module_str = str(self.module)
        elif isinstance(module, str):
            self.module = maude.getModule(module)
            self.module_str = module
        elif isinstance(module, maude.Module):
            self.module = module
            self.module_str = str(module)
        else:
            raise TypeError(
                f"unexpected type '{type(module).__name__}' for module")

        # Metamodule

        if isinstance(metamodule, str):
            self.metamodule = self.module.parseTerm(metamodule)
            self.module = maude.downModule(metamodule)
        elif isinstance(metamodule, maude.Term):
            self.metamodule = metamodule
            self.module = maude.downModule(metamodule)
        else:
            self.metamodule = None

        # Initial term

        if isinstance(initial, str):
            self.initial = self.module.parseTerm(initial)
            self.initial_str = initial
        elif isinstance(initial, maude.Term):
            self.initial = initial
            self.initial_str = str(initial)
        else:
            raise TypeError(
                f"unexpected type '{type(module).__name__}' for term")

        # Strategy expression

        if isinstance(strategy, str):
            self.strategy = self.module.parseStrategy(strategy)
            self.strategy_str = strategy
        elif isinstance(strategy, maude.StrategyExpression):
            self.strategy = strategy
            self.strategy_str = str(strategy)
        else:
            self.strategy = None
            self.strategy_str = None

        # Opaque strategies and biased_matchrew

        self.opaque = opaque
        self.biased_matchrew = biased_matchrew

        # Build the parser

        self.parser = _formulae.Parser()
        self.parser.set_module(self.module, metamodule=self.metamodule)

        # Look for the Formula sort

        formula_sort = self.module.findSort('Formula')
        if formula_sort is None:
            raise ValueError(
                'the given module is not prepared for model checking')
        self.formula_kind = self.module.findSort('Formula').kind()

        # Graphs (wrapped or not)

        if self.strategy is None:
            self.graph = maude.RewriteGraph(self.initial)
        else:
            self.graph = maude.StrategyRewriteGraph(self.initial,
                                                    self.strategy, self.opaque,
                                                    self.biased_matchrew)

        self.wgraphs = {}
        self.single_use = single_use
예제 #6
0
	def load(self):
		"""Load and check the extension"""

		# The module defining the extension and the required functions
		self.extension = maude.getModule(self.view)

		makeSlangGrammar_name = 'makeSlangGrammar'
		makeMetaSlang_name    = 'makeMetaSlang'

		if self.extension is None:
			view = maude.getView(self.view)

			if view is None:
				show_error('Not a module or view: ' + args.view)
				return False

			# Instantiating a view is not simple because the library does not offer many
			# tools for this, and because views may have been defined using op-to-term
			# mappings and the expected symbols may not be present in the module

			# Except the last two modules, this can be done once for all

			modid = uuid.uuid1()

			makeSlangGrammar_name = f'{modid}-makeSlangGrammar'
			makeMetaSlang_name    = f'{modid}-makeMetaSlang'

			# Create a strategy module where the functions makeSlangGrammar
			# and makeMetaSlang are properly defined
			maude.input(f'''smod MOD-{modid}{{X :: SLANG-EXTENSION}} is
				op {modid}-makeSlangGrammar : Module -> Module .
				op {modid}-makeMetaSlang : Module -> Module .
				var M : Module .
				eq {modid}-makeSlangGrammar(M) = makeSlangGrammar(M) .
				eq {modid}-makeMetaSlang(M) = makeMetaSlang(M) .
			endsm''')

			# Instantiate the view
			maude.input(f'''smod INST-{modid} is
				protecting MOD-{modid}{{{self.view}}} .
				protecting SMOD-PARSE{{{self.view}}} .
			endsm''')

			self.extension = maude.getModule(f'INST-{modid}')

		module_kind = self.extension.findSort('Module').kind()

		self.makeSlangGrammar = self.extension.findSymbol(makeSlangGrammar_name, [module_kind], module_kind)
		self.makeMetaSlang    = self.extension.findSymbol(makeMetaSlang_name, [module_kind], module_kind)

		if self.makeSlangGrammar is None or self.makeMetaSlang is None:
			show_error('Cannot find the expected operators in the extension module.')
			return False

		# Find the parseModule symbol (but do not fail if not found)
		string_kind           = self.extension.findSort('String').kind()
		self.stratModule_sort = self.extension.findSort('StratModule')

		self.parseModule = self.extension.findSymbol('parseModule', [string_kind], module_kind)
		self.flatModule = self.extension.findSymbol('flatModule', [module_kind], module_kind)

		return True
예제 #7
0
	# Load the Maude specifications of the extension and the model
	maude.init(advise=False)

	if not os.path.isfile(args.extension):
		show_error('Cannot find strategy language extension file: ' + args.extension)
		sys.exit(1)

	if not os.path.isfile(args.file):
		show_error('Cannot find Maude file: ' + args.file)
		sys.exit(1)

	maude.load(args.extension)
	maude.load(args.file)

	# The module where the extended strategies will be used...
	base_module = maude.getCurrentModule() if args.module is None else maude.getModule(args.module)

	# ...unless a metamodule is specified
	if args.metamodule is not None:
		metamodule = args.metamodule

		metamod_term = base_module.parseTerm(metamodule)
		module = maude.downModule(metamod_term)
		metamodule = str(metamod_term)

	elif args.extmodule is None:
		metamodule = f"upModule('{str(base_module)}, true)"
		module = base_module

	# Load the strategy language extension
	extension = SlangExtension(args.view)
예제 #8
0
 def __init__(self):
     super().__init__('maude_publisher')
     self.publisher_ = self.create_publisher(String, 'maude_msgs', 10)
     timer_period = 1.5  # seconds
     self.timer = self.create_timer(timer_period, self.timer_callback)
     self.maude_nat = maude.getModule('NAT')
예제 #9
0
    def __init__(self, implementation='a*', map_in_python=True):
        super().__init__('maude_planner_action_server'
                         )  # Node name, could be changed to fit the BT

        maude.init()
        maude.load(self.ASTAR_MAUDE_PATH[implementation])
        self.astar_module = maude.getModule('ASTAR')

        if self.astar_module is None:
            self.get_logger().fatal(
                'Cannot find Maude ASTAR module in {}'.format(
                    self.ASTAR_MAUDE_PATH[implementation]))
        else:
            self.get_logger().info('Maude planner node is ready')

        self.occupancy_grid = None  # It will be read and updated from the map topic
        self.maude_map = None
        self.amcl_pose = None  # It will be read and updated from the topic /amcl_pose

        # Configures the action server to respond to ComputePathToPose actions
        self._action_server = ActionServer(self, ComputePathToPose,
                                           'ComputePathToPose',
                                           self.action_callback)

        # Listen to map topic
        self._map_subscription = self.create_subscription(
            OccupancyGrid, 'global_costmap/costmap', self.map_callback,
            10)  # Queue size

        # Listen to topic /amcl_pose
        self._amcl_pose_subscription = self.create_subscription(
            PoseWithCovarianceStamped, 'amcl_pose', self.amcl_pose_callback,
            10)  # Queue size

        # Plan publisher (so that it is represented in the view)
        self._plan_publisher = self.create_publisher(Path, '/plan', 10)

        # Connect the Maude special operator to the map
        self.map_in_python = map_in_python

        if map_in_python:
            if implementation == 'a*':
                self.map_hook = MapProvider(self, self.astar_module)
                maude.connectEqHook('open2?', self.map_hook)
            else:
                self.map_hook = MapProviderGet(self)
                maude.connectEqHook('get', self.map_hook)

        # Find sorts and operators needed to construct the a* term
        # (once for all)
        m = self.astar_module
        pose_kind = m.findSort('Pose').kind()
        costmap_kind = m.findSort('CostMap').kind()
        float_kind = m.findSort('Float').kind()
        path_kind = m.findSort('Path').kind()
        int_kind = m.findSort('IntList').kind()

        #         Init Goal         NumRow NumCol
        # op a* : Pose Pose CostMap  Float  Float -> Path .
        self.astar_symb = m.findSymbol(
            self.ASTAR_OPNAME[implementation],
            [pose_kind, pose_kind, costmap_kind, float_kind, float_kind],
            path_kind)
        self.intlist_symb = m.findSymbol('_`,_', [int_kind] * 2, int_kind)
        self.cmap_symb = m.findSymbol('`{_`}', [int_kind], costmap_kind)

        # Constants that will be used multiple times
        self.zero_term = m.parseTerm('0')
        self.one_term = m.parseTerm('1')
        self.mtIL_term = m.parseTerm('mtIL')
예제 #10
0
    def __init__(self, test_path, obtain_navfn=True):
        with open(test_path, 'r') as ftest:
            lines = ftest.readlines()
            self.w, self.h = lines[0].strip().split()
            self.w = int(self.w)
            self.h = int(self.h)
            self.map_bin_file = lines[1].strip()  # Filename relative to the test case
            self.map_data = [0] * (self.w * self.h)  # Avoid appending
            test_full_path = os.path.abspath(ftest.name)
            test_dir = os.path.dirname(test_full_path)
            map_full_map_path = os.path.join(test_dir, self.map_bin_file)
            self.map_bin_file = map_full_map_path  # Full path

            with open(self.map_bin_file, 'rb') as fmap:
                for i in range(self.w * self.h):
                    cell = fmap.read(1)
                    self.map_data[i] = int.from_bytes(cell, 'big')  # It's one byte, it doesn't matter big or little endian
                
            self.test_cases = list()
            for test in lines[3:]:
                if test.strip().startswith('-1'):
                    continue
                x0, y0, x1, y1 = [float(c) for c in test.strip().split()]
                self.test_cases.append(((x0, y0, 0.0), (x1, y1, 0.0)))  # Orientation 0 degrees

        maude.init()
        maude.load(self.ASTAR_MAUDE_PATH)

        # Find sorts and operators needed to construct the a* term
        self.m       = maude.getModule('ASTAR')
        pose_kind    = self.m.findSort('Pose').kind()
        costmap_kind = self.m.findSort('CostMap').kind()
        float_kind   = self.m.findSort('Float').kind()
        path_kind    = self.m.findSort('Path').kind()
        int_kind     = self.m.findSort('IntList').kind()
        nat_kind     = self.m.findSort('Nat').kind()
        potential_kind = self.m.findSort('Potential').kind()
        gradient_kind = self.m.findSort('Gradient').kind()

        # We need it to solve an ambiguity later
        self.pose_kind = pose_kind

        # Use different functions whether obtaining the potential or not
        if not obtain_navfn:
            self.astar = self.m.findSymbol('a*',
                                           [pose_kind, pose_kind, costmap_kind]
                                           + [nat_kind] * 4,
                                           path_kind)
            self.get_potential = None
            self.compute_path = None

        else:
            self.astar = None

            # op getPotential : Pose Pose CostMap Nat Nat Nat -> Potential .
            self.get_potential = self.m.findSymbol('getPotential',
                                                   [pose_kind, pose_kind, costmap_kind, nat_kind, nat_kind, nat_kind],
                                                   potential_kind)

            # op computePath : CostMap Potential Pose Pose Float Gradient Nat Nat Nat -> Path .
            self.compute_path = self.m.findSymbol('computePath',
                                                  [potential_kind, pose_kind, pose_kind, float_kind, gradient_kind, nat_kind, nat_kind, nat_kind],
                                                  path_kind)

        intlist      = self.m.findSymbol('_`,_', [int_kind] * 2, int_kind) 
        cmap         = self.m.findSymbol('`{_`}', [int_kind], costmap_kind)

        self.pattern = self.m.parseTerm('{ X:Float, Y:Float, Z:Float } O:Nat')

        self.mod = self.m

        # Constants that will be used multiple times
        zero = self.m.parseTerm('0')
        one  = self.m.parseTerm('1')
        mtIL = self.m.parseTerm('mtIL')
        self.noPath = self.m.parseTerm('noPath')
        self.empyList = self.m.parseTerm('nil')
        
        # Dictionary with Maude integer terms from 0 to 255 to avoid parsing 
        # when constructing the map_list in Maude
        int_terms = dict()
        for i in range(0,256):
            int_terms[i] = self.m.parseTerm(str(i))

        # Build the IntList with the costmap data
        map_list = mtIL

	# There is no need to build the map, because it will be read from the hook
        # for c in self.map_data:
        #    map_list = intlist(map_list, int_terms[c])

        cycles = str(max(int(self.w * self.h / 20), self.w + self.h))  # Same number of cycles as ROS
        path_cycles = str(4 * self.w)
        self.static_args = [
            cmap(map_list),
            self.m.parseTerm(str(int(self.w))),
            self.m.parseTerm(str(int(self.h))),
            self.m.parseTerm(cycles),
            self.m.parseTerm(path_cycles),
        ]

        # Hook for "op get : CostMap Nat Nat Nat -> Float"
        class MapHook(maude.Hook):
            def __init__(self, parent):
                super().__init__()
                self.parent = parent  # DirectProfiler object to access attributes as the map or the Maude module for parsing
                self.cache = dict()  # Dictionary int in [0..255] -> Maude term representing the corresponding Float
                for i in range(0, 256):
                    self.cache[i] = self.parent.m.parseTerm(str(float(i)))
            
            def run(self, term, data):
                try:
                    _, x, y, ncols = [int(arg) for arg in term.arguments()]
                    cell_value = self.parent.map_data[y * ncols + x]
                    ret_term = self.cache[cell_value]
                    # print(f'FAST {term} --> {ret_term}')
                    return ret_term
                except Exception as e:
                    print('hook:', e)

        self.mapHook = MapHook(self)
        maude.connectEqHook('get', self.mapHook)
예제 #11
0
파일: common.py 프로젝트: fadoss/umaudemc
def parse_initial_data(args):
	"""Inits Maude and parse common initial data of a model-checking problem"""
	maude.init(advise=args.advise)

	data = InitialData()

	# Checks whether the file exists
	data.filename = find_maude_file(args.file)

	if data.filename is None:
		usermsgs.print_error('No such file.')
		return None

	if not maude.load(args.file):
		usermsgs.print_error('Error loading file')
		return None

	# Loads the module

	if args.module is None:
		data.module = maude.getCurrentModule()

		if data.module is None:
			usermsgs.print_error('No last module.')
			return None

	else:
		data.module = maude.getModule(args.module)

		if data.module is None:
			usermsgs.print_error(f'Module {args.module} does not exist.')
			return None

	# Loads a metamodule (if required)

	if args.metamodule is not None:
		mt = data.module.parseTerm(args.metamodule)

		if mt is None:
			usermsgs.print_error('Bad parse for metamodule term.')
			return None

		data.metamodule = mt
		data.module = maude.downModule(mt)

		if data.module is None:
			usermsgs.print_error('Bad metamodule.')
			return None

	# Parse the initial term

	data.term = data.module.parseTerm(args.initial)

	if data.term is None:
		usermsgs.print_error('Bad parse for initial term')
		return None

	# Parse the strategy

	if args.strategy is not None:
		data.strategy = data.module.parseStrategy(args.strategy)

		if data.strategy is None:
			usermsgs.print_error('Bad parse for strategy')
			return None

	else:
		data.strategy = None

	# Opaque strategies and full matchrew

	data.opaque = [] if args.opaque == '' else args.opaque.split(',')
	data.full_matchrew = args.full_matchrew

	return data
예제 #12
0
##
## Model checking
##

# Load Maude
maude.init(advise=False)

# Construct the module where to model check membrane systems
maude.load(args.file)

if args.module is None:
    args.module = str(maude.getCurrentModule())

maude.load('multistrat')

ms_external = maude.getModule('MULTISTRAT-EXTERNAL')

if ms_external is None:
    print(
        'Error: cannot find multistrategy infraestructure (multistrat.maude).')
    sys.exit(1)

term_kind = ms_external.findSort('Term').kind()
module_kind = ms_external.findSort('Module').kind()
strategy_kind = ms_external.findSort('StrategyList').kind()
ms_context = ms_external.findSort('MSContext').kind()
ms_threadset = ms_external.findSort('MSThreadSet').kind()
result_pair = ms_external.findSort('ResultPair')
strategy_sort = ms_external.findSort('Strategy')
ms_formula = ms_external.findSort('Formula').kind()
예제 #13
0
# Try to open the membrane specification file and prepare it
try:
	with open(args.file, 'r') as membf:
		membs = membf.read()

except FileNotFoundError as fnfe:
	print(fnfe)
	sys.exit(1)

# Escape line breaks and other to make this a Maude string
membs = membs.replace('\n', '\\n').replace('"', '\\"').replace('\t', ' ')

# Construct the module where to model check membrane systems
maude.load('memparse')

membrane_external = maude.getModule('MEMBRANE-EXTERNAL')
module_term = membrane_external.parseTerm(f'makeMMCModule("{membs}", {"false" if args.priority == "weak" else "true"}, {args.objbound})')
nrewrites = module_term.reduce()

if args.verbose:
	print(f'Rewriting model generated from membrane specification ({nrewrites} rewrites)')

# The rewrite theory for the membrane system as a Module object
mmc_module = maude.downModule(module_term)

if mmc_module is None:
	print('Error when computing the Maude module for the membrane system.')
	sys.exit(1)

# Parse the initial membrane
t = mmc_module.parseTerm(args.membrane)