GithubHelp home page GithubHelp logo

verites / verigraph Goto Github PK

View Code? Open in Web Editor NEW
37.0 6.0 4.0 2.98 MB

Software specification and verification system based on graph rewriting

Home Page: https://verites.github.io/verigraph/

License: Apache License 2.0

Haskell 92.85% Shell 0.24% Ruby 0.01% Gosu 0.95% Python 0.61% Lua 5.34%
haskell verification graph-grammars graph-transformation-systems category-theory graph verigraph

verigraph's Introduction

Verigraph

Build Status Coverage Status Code Climate Issue Count

Software specification and verification tool based on graph rewriting.

Version DOI License

Tutorial

In depth "how to" tutorials are available for each stable version at Releases.

Quick Start

Installing via Stack

First you must assure that stack is in version 1.6.0 or later. You can check the stack version with the command:

   $ stack --version

If the stack version is older, you can upgrade it by running:

  $ stack upgrade
  $ echo "export PATH=~/.local/bin:${PATH}" >> ~/.bashrc
  $ source ~/.bashrc

You may remove the previous installed stack package. Once you have cloned this repository, install verigraph by running:

  $ stack setup # Will download and configure ghc if it is not installed yet
  $ stack install

If there is an error saying /usr/bin/ld: cannot find -ltinfo, it means you don't have libtinfo.so in your /usr/lib directory (see judah/haskeline#57). You may install the lib package to fix this (In ubuntu the package libtinfo-dev installs this lib), and then run stack install again

If there is an error saying recompile with -fPIC, it can be fixed by the following command (see commercialhaskell/stack#2712).

  $ shopt -s globstar && sed -i 's/-fno-PIE/-no-pie/g' ~/.stack/programs/**/ghc-*/settings`

Installing via Cabal

Once you have cloned this repository, install verigraph by running:

  $ cabal install
  $ echo "export PATH=${PATH}:~/.cabal/bin" >> ~/.bashrc
  $ source ~/.bashrc

Usage

Run verigraph helper:

  $ verigraph --help

Some example grammars are provided in the grammars directory, try something like:

  $ verigraph analysis grammars/Pacman/pacman.ggx

If you use bash, you can enable autocompletion of verigraph options for the current session by running the following command.

  $ source <(verigraph --bash-completion-script "$(which verigraph)")

Modelling and Visualization

We use AGG to read and write the .ggx and .cpx files with the Graph Grammars and their analysis.

Contributing

We encourage you to contribute to Verigraph. Please check out the Contributing guidelines about how to proceed.

Everyone interacting in Verigraph and/or its tutorials, sub-projects' codebases and issue trackers is expected to follow the Contributor Covenant Code of Conduct.

License

Verigraph is released under the Apache 2.0 License

verigraph's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

verigraph's Issues

Reduce dictionary lookups and Maybes in the Graph API

The API of module Graph.Graph forces frequent lookups into the association lists, which probably incurs a performance penalty. Also, its functions often return Maybes where the result could be guaranteed to exist.

In order to reduce these issues, a notion of "node context" could be introduced, which allows the user to access the incident edges of a node. This would make the lookups implicit, and the well-formedness of the graphs ensures that such lookups do not fail.

The following is a sketch of the additions/changes to Graph.Graph module

data Node n =
    Node NodeId (Maybe n)

data Edge e =
    Edge EdgeId NodeId NodeId (Maybe e)

type NodeInContext n e =
    (Node n, NodeContext n e)

type EdgeInContext n e =
    (NodeInContext n e, Edge e, NodeInContext n e)

-- The constructor for NodeContext is not exported.
data NodeContext n e =
    NodeContext NodeId (Graph n e)

lookupNodeInContext :: NodeId -> Graph n e -> Maybe (NodeContext n e)

incidentEdges :: NodeContext -> [EdgeInContext n e]

incomingEdges :: NodeContext -> [EdgeInContext n e]

outgoingEdges :: NodeContext -> [EdgeInContext n e]

As an example of usage, this is an implementation of depth-first search using the contexts.

depthFirstSearch :: NodeInContext n e -> [Node n]
depthFirstSearch initialNode =
    search IntSet.empty [initialNode]
    
  where
    search _ [] = []
    
    search visitedNodes ((node, context) : rest) =
      if node `IntSet.member` visitedNodes then
        search visitedNodes rest
      else 
        let
          nextNodes =
            [ target | (_, _, target) <- outgoingEdges context ]
              
        in
          node :: search (IntSet.insert (nodeId node) visitedNodes) (nextNodes ++ rest)

Make graph payloads mandatory

Rationale

Currently, the payloads of graph nodes and edges are optional. That is, in a Graph n e, nodes contain payloads of type Maybe n and edges, of type Maybe e. There is currently, however, no use for these payloads in Verigraph, not even to allow metadata such as graph layout (since payloads are not handled and propagated by pullbacks, pushouts, overlappings and similar operations).

One of the possible uses would be to store attributes and typing information, which would reduce the number of dictionary lookups necessary to handle typed attributed graphs, simplifying code and improving performance. This, however, is not possible with optional payloads, since all nodes and edges need to have this information.

In order to allow this, graphs would need to have mandatory payloads. That is, in a Graph n e, nodes would contain payloads of type n and edges, of type e. Then, typed attributed graphs could be implemented simply as follows.

import qualified Graph as G

type AttributedGraph n e = 
  G.Graph (NodeType, Map AttrName AttrValue, n) (EdgeType, Map AttrName AttrValue, e)

type Node n =
  G.Node (NodeType, Map AttrName AttrValue, n)
  
type Edge e =
  G.Edge (EdgeType, Map AttrName AttrValue, e)
    
nodeType :: Node n -> NodeType
nodeType = fst . G.nodeInfo

edgeType :: Edge n -> EdgeType
edgeType = fst . G.edgeInfo

nodeInfo :: Node n -> n
nodeInfo = third . G.nodeInfo

edgeInfo :: Edge e -> e
edgeInfo = third . G.edgeInfo

This implementation pattern has the following advantages:

  • A single lookup gives all information about a node or edge, simplifying code and improving efficiency.

  • Most of the Graph API would be immediately applicable to specialized graph types, without the need for separate functions as is currently done in for TypedGraphs

Proposed Changes

First, change the implementation of Graph so its has mandatory payloads. The impact of this change in the rest of Verigraph could be handled in two ways, based on Graph () () (unit-based) or on Graph (Maybe n) (Maybe e) (maybe-based).

Unit-Based Solution

Since no part of verigraph currently uses the payloads, they could be replaced with unit types whenever they are "ignored" by functions. We'd have, for example:

insertNode :: NodeId -> Graph () e -> Graph () e
insertNodeWithPayload :: NodeId -> n -> Graph n e -> Graph n e

instance Morphism (GraphMorphism () ())

instance Morphism (TypedGraphMorphism () ())

Maybe-Based Solution

Alternatively, we could displace the assumption of optional payloads to the function signature. That is, whenever Nothing is required to be a possible node payload, the type signature contains Graph (Maybe n) e (analogously for edges). We'd have, for example:

insertNode :: NodeId -> Graph (Maybe n) e -> Graph (Maybe n) e
insertNodeWithPayload :: NodeId -> n -> Graph n e -> Graph n e

instance Morphism (GraphMorphism (Maybe n) (Maybe e))

instance Morphism (TypedGraphMorphism (Maybe n) (Maybe e))

Define JSON input/output format to Web API

JSON as input/output format will make integration between verigraph and other tools (including @Verites/verigraph-gui ) easier.

So, we need define a JSON format to verigraph.

Resolve warnings from compiler

With the changes introduced on the api by #11 there are a big number of warnings from the compiler. We should make an effort to resolve them as soon as possible, since this makes logs difficult to read.

Refactor FinitaryCategory Type Class

Refactor the Morphism type class, renaming it to FinitaryCategory to better match its responsabilities.

At the same time, implement @ggazzi's suggestion of using a Context Monad to store important information about the category, such as the type graph of a TGraph and the type graph and NAC strategy of a TSpan.

  • Rename Morphism to FinitaryCategory
  • Add a "context monad" to the type classes
  • Flip the arguments of compose and add an alias (<&>)
    • To do the same thing for Data.Relation ?
  • Integrate FindMorphism into FinitaryCategory

M-Adhesive categories

Some categories have different classes of morphism, not just epi/mono/iso. In particular, some categories are adhesive with respect to a subclass N of monomorphisms. Some will further restrict the morphisms which are allowed in productions.

An example is Symbolic Graph Transformation, where rules must be monomorphic in the graph component and isomorphic in the attribute component.

These are not contemplated in the current architecture.

(Untyped) Symbolic Graphs and Morphisms with Integers

Implement a data type for (untyped) symbolic graphs and morphisms, including instances of Morphism, FindMorphism, EpiPair, AdhesiveHLR.

The base algebra should support only integers. The graphs are untyped, and each node contains a single integer attribute. Edges have no attributes.

Unclear preconditions for induceSpanMorphism

The method induceSpanMorphism of the FindMorphism class will sometimes generate an invalid morphism, since the desired morphism doesn't always exist.

This should be documented, or even better, it should return Nothing when the morphism doesn't exist.

Add types to symbolic graphs

Allow user-defined node/edge types in symbolic graphs. Allow user-defined attributes for each of these types.

Export rule sequences

Verigraph does not export the rule sequences of the original input GGX file to the output one.

Abnormal behaviour on GraphMorphism equality

While writing some tests, I found an abnormal behaviour on the equality tests of Graph Morphisms, the problem seems to be w.r.t. Relations Equality Comparison.

Test

spec :: Spec
spec = describe "Graph Morphism API" $ do

  describe "removeNodeFromCodomain" $ do

  it "Should remove node without incident edges" $ do
      (nodeRelation $ removeNodeFromCodomain 3 g1) `shouldBe` (nodeRelation g4)

Output

Graph.GraphMorphism, Graph Morphism API, removeNodeFromCodomain, Should remove node without incident edges
       expected: Relation {domain = [1,2,4,3], codomain = [1,2,4], mapping = fromList [(1,[1]),(2,[2]),(4,[4])]}
        but got: Relation {domain = [1,2,3,4], codomain = [1,2,4], mapping = fromList [(1,[1]),(2,[2]),(3,[]),(4,[4])]}

Context

g1' :: Graph (Maybe a) (Maybe b)
g1' = build [1,2,3,4] [(1,1,2)]

g2' :: Graph (Maybe a) (Maybe b)
g2' = build [1,2,4] [(1,1,2)]

g1 :: GraphMorphism (Maybe a) (Maybe b)
g1 = buildGraphMorphism g1' g1' [(1,1),(2,2),(3,3),(4,4)] [(1,1)]

g4 :: GraphMorphism (Maybe a) (Maybe b)
g4 = buildGraphMorphism g1' g2' [(1,1),(2,2),(4,4)] [(1,1)]

Modules Refactoring

There are some operations spread among the modules of DPO and AdhesiveHLR that do not appear to be in the right place. Specially regarding NACs and rewritting. Such as:

DPO:
nacDownwardShift

AdhesiveHLR:
MatchRestriction
matchRestrictionToMorphismType
NacSatisfaction

Since we are in a process of refactoring the projects architecture, should we create new specific modules for?

  • NAC-Adhesive Categories
    • Renaming the current module?
  • Abstract Rewritting Approaches
  • DPO Rewritting approach outside the Category module
  • Change MatchRestriction to MorphismType.

Related Issues:

Import/Export AGG Attributes

Verigraph does not import/export attributes from/to GGX file.

It will allow Verigraph to manipulate grammars with attributes without changing them.

Grammar with Multiplicities

Investigate the implementation of multiplicities in the type graph and the corresponding restrictions over the grammar and the analyses provided by verigraph.

Migrate all tests to default approach

Currently, some of the tests are using plain HUnit and some are using Hspec with HUnit and QuickCheck. We should unify all tests under a single style.

Improve messages for malformed graphs, rules, grammars, etc

Currently, the function valid returns a Bool, which is not helpful when we need to fix a malformed value. It should be changed to return a Maybe String, producing appropriate error messages. We must also think about how to handle the context in which errors occur.

Properly handle node/edge metadata

Rationale

Sometimes it would be useful to associate some metadata to nodes and edges, that is used e.g. for the GUI or documentation purposes, and have it properly handled and propagated to outputs.

A simple example are the positions of nodes. It could be useful for critical pairs to have a (preliminary) node layout that is based on the node layout of the rules. This layout would then be refined by some algorithm in the GUI.

In order to do this, we'd probably need to include this metadata into the payloads of nodes and edges. We'd also need to figure out how to properly handle these payloads in basic categorial operations such as pullbacks, pushouts, overlappings, etc. This would probably involve having a type class with the necessary operations.

Monoidal Metadata

A first suggestion would be to use the Monoid class, which describes types that have an "empty" value and can be arbitrarily combined. Then any elements created from scratch would have the "empty metadata, elements created from a single other element would have the metadata copied and elements created from multiple other elements (e.g. in an overlapping or pushout) would have the metadata combined.

In the example of using positions, the following type could be used as metadata:

type Position
  = Position Float Float
  | NoPosition
  
  
instance Monoid Position where
  mempty = NoPosition
  
  mappend NoPosition p = p
  mappend p NoPosition = p
  mappend (Position x1 y1) (Position x2 y2) = Position ((x1+x2)/2) ((y1+y2)/2)

We still have to check if Monoid is enough, and how exactly the metadata is propagated by the primitive operations.

Inconsistent behaviour when removing nodes

The function removeNodeFromDomain from the GraphMorphism module does not remove a node that has incident edges, which is the default behaviour of verigraph in order to not generate invalid structures.

However, it still removes the mapping of the node to its image, which may lead to invalid graphs.

Create and document code style

The following draft should be finished and published to Coding Style Guide

Verigraph Coding Style

This is a short document based on Johan Tibell's style guide describing the preferred coding style for this project. Some of these rules can be enforced by stylish-haskell, using the configuration file in the project root.

Formatting

Line Length

Maximum line length is 100 characters. "Going over is not the end of the world, but consider refactoring before you decide a line really must be longer."¹

Indentation

Tabs are illegal. Use spaces for indenting. Always indent to multiples of two.

Blank Lines

Whitespace

Export Lists

Data Declarations

Pragmas

Lists

Hanging Lambdas

Case Expressions

If-then-else Clauses

Imports

Comments

Punctuation

Top-Level Definitions

End-of-Line Comments

Links

Naming

Modules

Dealing with Laziness

Misc

Point-free style

Warnings

¹ As in the Elm style guide

Import of type graph from GGX

Verigraph does not support GGX files that contains different edge types with the same ID but different node types for source and target.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.