From 6908956bc0ddbade6c3d6679dab9fd9cdf82a8db Mon Sep 17 00:00:00 2001 From: engboris Date: Tue, 2 May 2023 20:01:08 +0200 Subject: [PATCH] =?UTF-8?q?Reprogrammation=20compl=C3=A8te?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 27 +- Makefile | 26 ++ README.md | 118 ++++++- _build/_log | 2 + _build/sanitize.sh | 8 + automata.stellar | 12 + haskell/ArithmeticsPL.hs | 39 --- haskell/Main.hs | 9 - haskell/PrettyPrinter.hs | 21 -- haskell/Resolution.hs | 260 --------------- haskell/Unification.hs | 94 ------ instructions.pdf | Bin 149244 -> 0 bytes lexer.ml | 212 +++++++++++++ lexer.mll | 27 ++ loop.stellar | 1 + main.ml | 136 ++++++++ mllcorrectness.stellar | 3 + mllcutelim.stellar | 3 + ocaml/Circuits.ml | 107 ------- ocaml/FSA.ml | 32 -- ocaml/Resolution.ml | 250 --------------- ocaml/StellarCircuits.ml | 55 ---- ocaml/StellarFSA.ml | 15 - ocaml/Unification.ml | 92 ------ ocaml/main.ml | 49 --- parser.ml | 666 +++++++++++++++++++++++++++++++++++++++ parser.mli | 27 ++ parser.mly | 37 +++ prolog.stellar | 8 + stellar.ml | 123 ++++++++ tools.ml | 21 ++ unification.ml | 85 +++++ 32 files changed, 1511 insertions(+), 1054 deletions(-) create mode 100644 Makefile create mode 100644 _build/_log create mode 100644 _build/sanitize.sh create mode 100644 automata.stellar delete mode 100644 haskell/ArithmeticsPL.hs delete mode 100644 haskell/Main.hs delete mode 100644 haskell/PrettyPrinter.hs delete mode 100644 haskell/Resolution.hs delete mode 100644 haskell/Unification.hs delete mode 100644 instructions.pdf create mode 100644 lexer.ml create mode 100644 lexer.mll create mode 100644 loop.stellar create mode 100644 main.ml create mode 100644 mllcorrectness.stellar create mode 100644 mllcutelim.stellar delete mode 100644 ocaml/Circuits.ml delete mode 100644 ocaml/FSA.ml delete mode 100644 ocaml/Resolution.ml delete mode 100644 ocaml/StellarCircuits.ml delete mode 100644 ocaml/StellarFSA.ml delete mode 100644 ocaml/Unification.ml delete mode 100644 ocaml/main.ml create mode 100644 parser.ml create mode 100644 parser.mli create mode 100644 parser.mly create mode 100644 prolog.stellar create mode 100644 stellar.ml create mode 100644 tools.ml create mode 100644 unification.ml diff --git a/.gitignore b/.gitignore index 6a62767..61e76dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,4 @@ -# ---> Haskell -dist -dist-* -cabal-dev -*.o -*.hi -*.hie -*.chi -*.chs.h -*.dyn_o -*.dyn_hi -.hpc -.hsenv -.cabal-sandbox/ -cabal.sandbox.config -*.prof -*.aux -*.hp -*.eventlog -.stack-work/ -cabal.project.local -cabal.project.local~ -.HTF/ -.ghc.environment.* +main +*.cmi +*.cmo diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..951a058 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +CC = ocamlc +MAIN = main + +all: $(MAIN) + +$(MAIN): tools.cmo unification.cmo stellar.cmo parser.cmo lexer.cmo main.cmo + $(CC) $^ -o $(MAIN) + +parser.ml: parser.mly + menhir --infer $^ + $(CC) -c parser.mli + +lexer.ml: lexer.mll + ocamllex $^ + +%.cmo: %.ml + $(CC) -c $^ + +%.cmi: %.mli + $(CC) -c $^ + +.PHONY: clean + +clean: + @echo "Project clean." + @rm -rf *.cmi *.cmo *.cmx *.mli *.o parser.ml lexer.ml parser.conflicts main \ No newline at end of file diff --git a/README.md b/README.md index c8b24e3..20c5319 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,122 @@ # Large Star Collider -Réalisation de la résolution stellaire. +La résolution stellaire est un modèle de calcul proche de la résolution du premier ordre de Robinson qui est utilisée en programmation logique. Ce programme est une réalisation en OCaml de ce modèle de résolution stellaire. -## Réalisation en OCaml +Un **rayon** est un terme du premier ordre +``` +r := X | f(r1, ..., rn) +``` +où `f` est un symbole de fonction qui peut être préfixé ou non d'une polarité `+` ou `-` (par exemple `+f` et `-f`). Dans ce programme, on pourra aussi utiliser le symbole de fonction binaire `.` qui est infixe et associatif à droite (c'est-à-dire qu'on écrit `a . b . c` pour signifier `a . (b . c)`). Ce symbole est très utile pour créer des séquences de caractères (par exemple pour les mots en entrée des automates). -Il faut dans un premier temps traduire Unification.hs en OCaml et bien commenter le programme pour réaliser l'unification entre termes. Tester le programme sur des exemples divers. +Deux rayons qui contiennent des symboles polarisés peuvent être connectés lorsqu'ils sont unifiables sachant que les symboles de fonction identiques modulo inversion de polarité sont compatibles (habituellement, seuls les symboles égaux le sont). -L'objectif est de réaliser un modèle de calcul appelé "résolution stellaire" qui fonctionne avec des agents indépendants appelés "étoiles" qui calculent en entrant mutuellement en interaction (de façon asynchrone et concurrente). Ces étoiles ont des termes polarisés attachés appelés rayons. L'interaction détruit les rayons connectés et propage la solution de l'équation associée aux rayons connectés aux rayons adjacents. +Une **étoile** est une séquence de rayons qu'on peut considérer comme une clause dans un langage de programmation. +``` +[r1, ..., rn] +``` +Les étoiles sont capables d'interagir ensemble le long de rayons connectables par la règle de résolution de Robinson. Par exemple : `[X, -f(X)]` et `[+f(a)]` connectés ensemble le long du symbole `f` donne `[a]`. -Il faudra dans un premier temps comprendre comment le modèle de calcul fonctionne. En particulier, il faudra comprendre la notion de graphe de dépendance, diagramme, de fusion/actualisation et d'exécution de constellation présentée dans l'article de Eng en références. -L'idée de ce projet est que ce modèle de calcul est plutôt difficile à réaliser tel que décrit par la théorie mais qu'il existe en fait une manière beaucoup plus naturelle et satisfaisante de la programmer. Il faut voir le graphe de dépendance comme une sorte d'automate qu'on peut parcourir avec des jetons (voir document PDF dans le dépôt). +Une **constellation** est une union disjointe d'étoiles séparées par le symbole `+`. On peut considérer que les constellations sont des sortes de programmes dans ce modèle. Une constellation est délimitée par des accolades. +``` +{ [r11, ..., r1n] + ... + [rn1, ..., rnm] } +``` + +Ce que l'on cherche à exécuter n'est pas une constellation mais un **espace d'interaction**. C'est une expression de la forme : +``` + |- +``` +La constellation à gauche de `|-` est la *constellation de référence* et la constellation de droite est *l'espace d'interaction*. L'idée de l'exécution est que les étoiles de l'espace d'interaction va se mettre à jour en interagissant avec des copies d'étoiles voisines mais aussi des copies d'étoiles de la constellation de référence. + +En termes de programmation logique, la constellation de référence est la base de connaissance et l'espace d'interaction est un ensemble de requêtes. Contrairement à la programmation logique (par exemple en Prolog), il n'y a aucune vraie distinction entre une requête et une autre clause. Nous avons donc un espace de résolution de contraintes avec une partie statique dont on tire des étoiles et l'autre dynamique où l'ont construit des solutions. + +## Compilation + +``` +make +``` + +Pour supprimer les fichiers de compilation et nettoyer le projet : + +``` +make clean +``` + +## Usage + +Il faut simplement lancer l'exécutable `main`. + +``` +./main +``` + +Vous pouvez utiliser les commandes suivantes : +- `exit` pour quitter le programme (ou le mode interactif). +- `exec -f ` pour exécuter l'espace d'interaction contenu dans le fichier de nom ``. +- `exec ` pour exécuter l'espace d'interaction ``. +- `intmode` lance le mode interactif avec la constellation vide comme constellation initiale (voir section "Mode interactif"). +- `intmode -f ` lance le mode interactif avec la constellation définie dans `` (voir section "Mode interactif"). +- `intmode ` lance le mode interactif avec la constellation `` (voir section "Mode interactif"). +- `disable-loops` interdit les équations de la forme `X=X` qui peuvent mener à des boucles triviales. +- `enable-loops` autorise les boucles triviales. + +## Mode interactif + +Le mode interactif est un mode ludique adapté aux grands et petits (âge minimum conseillé : 8 ans). Vous démarrez à partir de la constellation initiale vide `{}`. Toutes les constellations que vous écrivez vont interagir et mettre à jour votre constellation. + +Petite astuce : si vous écrivez une constellation qui ne peut interagir avec aucune étoile, cela va simplement l'ajouter à la constellation. Cela permet de remplir petit à petit votre constellation. + +## Exemples + +Certains exemples avec l'extension `.stellar` sont déjà prêts à être exécutés. Ci-dessous, je présente quelques moyens de créer vos propres exemples. Dans mon manuscrit de thèse, vous retrouverez des méthodes pour réaliser de nombreux autres modèles comme des machines de Turing, automates à piles, transducteurs ou automates alternants de façon très simple. + +### Programmes logiques + +Les faits sont des étoiles `[+p(t)]` et les règles d'inférences sont des étoiles `[-p(t1)]` + +### Construire des automates finis + +L'encodage d'un automate fini doit nécessairement avoir les deux étoiles suivantes : +- `[-i(W), +a(W, q0)]` encodant l'état initial (où `q0` peut être remplacé par un autre nom) +- `[-a(e, qf), accept]` encodant l'état final (où `qf` peut être remplacé par un autre nom et `e` représente le mot vide "epsilon") + +Chaque transition d'un état `q1` vers un état `q2` le long d'une lettre `a` est encodée par une étoile +``` +[-a(a . W, q1), +a(W, q2)] +``` + +Les mots sont encodés par des séquences de caractères séparés par l'opérateur binaire `.` et terminant par `e`. Par exemple `0 . 0 . 1 . e` ou `e` ou encore `1 . b . c . e`. + +Il faudra ensuite placer l'automate comme constellation de référence et l'étoile correspondant au mot comme seule étoile de l'espace d'interaction. Exemple d'espace d'interaction pour un automate : + +``` +{ + [-i(W), +a(W, q0)] + + [-a(e, q2), accept] + + [-a(0 . W, q0), +a(W, q0)] + + [-a(1 . W, q0), +a(W, q0)] + + [-a(0 . W, q0), +a(W, q1)] + + [-a(0 . W, q1), +a(W, q2)] +} +|- +{ + [+i(0 . 0 . 0 . e)] +} +``` + +### Construire des preuves de la logique linéaire multiplicatives + +Il est recommandé de suivre la construction proposée dans mon manuscrit de thèse. On traduit chaque axiome par une étoile binaire contenant la traduction des atomes associés. + +La traduction d'un atome `a` accessible par une conclusion `c` est donnée par un rayon `+c(t)` où `t` est une séquence de symboles `l` (left) et `r` (right) séparés par l'opérateur binaire `.` et terminant par la variable `X`. L'idée pour la construction de `t` est qu'il encode le chemin de `c` à `a`. + +Par exemple si à partir d'une conclusion `c`, on a besoin de remonter en allant deux fois à gauche puis une fois à droite pour atteindre `a`, la traduction de `a` sera `+c(l.l.r.X)`. + +Une coupure connectant les conclusions `c1` et `c2` est encodée par l'étoile `[-c1(X), -c2(X)]`. + +Étant donné que les structures de preuves peuvent être parcourues en commençant par n'importe quel atome libre, il suffit de placer une étoile avec un atome libre (non polarisé dans ce cas) dans l'espace d'interaction et utiliser le reste de la structure de preuve comme constellation de référence. Plus tard, je vais sûrement ajouter un mode "auto" pour sélectionner automatiquement une étoile de départ car ce n'est pas toujours nécessaire de le faire. ## Références - Term Rewriting and All That. Baader, Franz. -- [A gentle introduction to Girard's Transcendental Syntax for the linear logician. Eng.](https://hal.archives-ouvertes.fr/hal-02977750) \ No newline at end of file +- Le manuscrit de thèse de Boris Eng qui n'est pas encore sorti. \ No newline at end of file diff --git a/_build/_log b/_build/_log new file mode 100644 index 0000000..ff83643 --- /dev/null +++ b/_build/_log @@ -0,0 +1,2 @@ +### Starting build. +# Compilation unsuccessful. diff --git a/_build/sanitize.sh b/_build/sanitize.sh new file mode 100644 index 0000000..045f073 --- /dev/null +++ b/_build/sanitize.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# File generated by ocamlbuild + +cd /mnt/e/Multimedia/Documents/Programming/large-star-collider + +rm -f lexer.ml +# Also clean the script itself +rm -f /mnt/e/Multimedia/Documents/Programming/large-star-collider/_build/sanitize.sh diff --git a/automata.stellar b/automata.stellar new file mode 100644 index 0000000..2a58ba8 --- /dev/null +++ b/automata.stellar @@ -0,0 +1,12 @@ +{ + [-i(W), +a(W, q0)] + + [-a(e, q2), accept] + + [-a(0 . W, q0), +a(W, q0)] + + [-a(1 . W, q0), +a(W, q0)] + + [-a(0 . W, q0), +a(W, q1)] + + [-a(0 . W, q1), +a(W, q2)] +} +|- +{ + [+i(0 . 0 . 0 . e)] +} \ No newline at end of file diff --git a/haskell/ArithmeticsPL.hs b/haskell/ArithmeticsPL.hs deleted file mode 100644 index f1e2bb9..0000000 --- a/haskell/ArithmeticsPL.hs +++ /dev/null @@ -1,39 +0,0 @@ -module ArithmeticsPL where -import Unification -import Resolution -import Data.Semigroup -import Data.Maybe - -vw = Var "w" -vx = Var "x" -vy = Var "y" -vz = Var "z" -z = Func "0" [] -s n = Func "s" [n] - -sn 0 b = b -sn n b = s (sn (n-1) b) - -add x y z = Func "add" [x, y, z] -mult x y z = Func "mult" [x, y, z] - -s1 = Star [Pos (add z vy vy)] -s2 = Star [Pos (add (s vx) vy (s vz)), Neg (add vx vy vz)] - -cadd :: Constellation -cadd = Const [ - Star [Pos (add z vy vy)], - Star [Pos (add (s vx) vy (s vz)), Neg (add vx vy vz)]] - -qadd :: Int -> Int -> Constellation -qadd n m = cadd <> - Const [Star [Neg (add (sn n z) (sn m z) (Var "r")), NC (Var "r")]] - -cmult :: Constellation -cmult = Const [ - Star [Pos (mult z vx z)], - Star [Pos (mult (s vx) vy vz), Neg (mult vx vy vw), Neg (add vy vw vz)]] - -qmult :: Int -> Int -> Constellation -qmult n m = cadd <> cmult <> - Const [Star [Neg (mult (sn n z) (sn m z) (Var "r")), NC (Var "r")]] diff --git a/haskell/Main.hs b/haskell/Main.hs deleted file mode 100644 index 8980973..0000000 --- a/haskell/Main.hs +++ /dev/null @@ -1,9 +0,0 @@ -module Main where -import Unification -import Resolution -import Data.Maybe -import ArithmeticsPL -import qualified Data.Set as Set - -main = do - return () diff --git a/haskell/PrettyPrinter.hs b/haskell/PrettyPrinter.hs deleted file mode 100644 index 3cd5532..0000000 --- a/haskell/PrettyPrinter.hs +++ /dev/null @@ -1,21 +0,0 @@ -module PrettyPrinter where -import Data.Maybe -import qualified Data.Set as Set - -{- Stars -} - -addsymbol :: Char -> Maybe Char -> [String] -> String -addsymbol _ after [] = "" -addsymbol sym after (w:ws) = w ++ go ws - where - go [] = "" - go (v:vs) = - case after of - Nothing -> sym : (v ++ go vs) - Just after' -> sym : after' : (v ++ go vs) - -addop :: Char -> [String] -> String -addop op w = addsymbol op Nothing w - -addcomma :: [String] -> String -addcomma = addsymbol ',' (Just ' ') diff --git a/haskell/Resolution.hs b/haskell/Resolution.hs deleted file mode 100644 index 1352cf0..0000000 --- a/haskell/Resolution.hs +++ /dev/null @@ -1,260 +0,0 @@ -module Resolution where -import qualified Unification -import Data.Maybe -import Data.List -import Data.Tuple -import PrettyPrinter as PrettyPrinter -import Control.Arrow -import Control.Monad -import Data.Semigroup -import qualified Data.Set as Set - -{- ======================================== - Definitions - ======================================== -} - -data Polarized a = Pos a | Neg a | NC a deriving (Ord, Eq) -type Ray = Polarized Unification.Term -newtype Star = Star { get_star :: [Ray] } -newtype Constellation = Const { get_const :: [Star] } -newtype Link = Link { get_link :: ((Ray, Ray), Int, Int) } -newtype StarGraph = StarGraph { get_graph :: ([Star], [Link]) } -type UGraph = StarGraph -type Diagram = StarGraph - -instance Functor Polarized where - fmap f (Pos t) = Pos (f t) - fmap f (Neg t) = Neg (f t) - fmap f (NC t) = NC (f t) - -instance Eq Star where - (Star s1) == (Star s2) = sort s1 == sort s2 - -instance Eq Constellation where - (Const s1) == (Const s2) = sort s1 == sort s2 - -instance Eq Link where - Link (e, i, j) == Link (e', i', j') = - (i==i' && j==j' && i/=j) || (i==i' && j==j' && i==j && e==swap e') - -instance Ord Star where - compare (Star s1) (Star s2) = compare s1 s2 - -instance Show a => Show (Polarized a) where - show (Pos t) = "+" ++ show t - show (Neg t) = "-" ++ show t - show (NC t) = show t - -instance Show Star where - show (Star s) = show s - -instance Show Constellation where - show (Const c) = show $ PrettyPrinter.addop '+' (map show c) - -instance Show Link where - show (Link x) = show x - -instance Show StarGraph where - show (StarGraph (v, e)) = - "------------------------\n" ++ - "Vertices:\n" ++ unlines (mapInd (\x i -> show i ++ ":" ++ show x) v) ++ - "Edges:\n" ++ unlines (map show e) - -instance Semigroup Constellation where - (Const c1) <> (Const c2) = Const (c1 ++ c2) - -mapInd :: (a -> Int -> b) -> [a] -> [b] -mapInd f l = zipWith f l [0..] - -change_color :: String -> String -> Ray -> Ray -change_color s s' r@(Neg (Unification.Func f ts)) - | f==s = Neg (Unification.Func s' ts) -change_color s s' r@(Pos (Unification.Func f ts)) - | f==s = Neg (Unification.Func s' ts) -change_color _ _ r = r - -dual :: Ray -> Ray -> Bool -dual (Pos _) (Neg _) = True -dual (Neg _) (Pos _) = True -dual _ _ = False - -get_term :: Ray -> Unification.Term -get_term (Pos t) = t -get_term (Neg t) = t -get_term (NC t) = t - -vars_ray :: Ray -> [Unification.Id] -vars_ray (Pos t) = Unification.vars t -vars_ray (Neg t) = Unification.vars t -vars_ray (NC t) = Unification.vars t - -vars_star :: Star -> [Unification.Id] -vars_star (Star s) = concat $ map vars_ray s - -subst_ray :: Unification.Subst -> Ray -> Ray -subst_ray = fmap . Unification.subst - -subst_rays :: Unification.Subst -> [Ray] -> [Ray] -subst_rays = map . subst_ray - -extends_ray :: String -> Ray -> Ray -extends_ray = fmap . Unification.extends_varname - -extends_star :: String -> Star -> Star -extends_star s (Star e) = Star (map (extends_ray s) e) - -rays :: Constellation -> [Ray] -rays (Const cs) = [r | s<-cs, r<-(get_star s)] - -{- ======================================== - Unification graph - ======================================== -} - -matchable_rays :: Ray -> Ray -> Bool -matchable_rays r1 r2 = dual r1 r2 && - Unification.matchable (get_term r1, get_term r2) - -get_links :: Star -> Star -> [(Ray, Ray)] -get_links (Star s1) (Star s2) = - [(r1, r2) | r1<-s1, r2<-s2, matchable_rays r1 r2] - -ugraph :: Constellation -> UGraph -ugraph (Const cs) = - let imax = length cs - 1 in - let pairs = [(i, j) | i<-[0..imax], j<-[0..imax], i<=j] in - let e = foldl (\acc (i, j) -> - let links = get_links (cs!!i) (cs!!j) in - let make_edge e = Link (e, i, j) in - if links==[] then acc else (map make_edge links) ++ acc) [] pairs in - StarGraph (cs, nub e) - -{- ======================================== - Actualisation - ======================================== -} - -make_edge :: [Star] -> (Int, Int) -> (Int, Int) -> Link -make_edge xs (is1, ir1) (is2, ir2) = - let (Star s1) = xs !! is1 in - let (Star s2) = xs !! is2 in - Link ((s1!!ir1, s2!!ir2), is1, is2) - -equations :: Diagram -> [Unification.Equation] -equations (StarGraph (v, e)) = - map (\(Link ((t, u), i, j)) -> - let new_t = Unification.extends_varname (show i) (get_term t) in - let new_u = Unification.extends_varname (show j) (get_term u) in - (new_t, new_u)) e - -appears_in_link :: Ray -> Link -> Bool -appears_in_link r (Link ((t, u), _, _)) = r==t || r==u - -already_linked :: Link -> [Link] -> Bool -already_linked (Link ((t, u), i, j)) ls = - any (\(Link ((t', u'), i', j')) -> - (t==t' && i==i') || (u==u' && j==j') || - (t==u' && i==j') || (u==t' && j==i')) ls - -free_rays :: Diagram -> [Ray] -free_rays (StarGraph (v, e)) = - let linked = concat [[(extends_ray (show i) r, i), (extends_ray (show j) r', j)] | (Link ((r, r'), i, j))<-e] in - let stars = mapInd (curry id) v in - let rays = concat $ map (\(Star s, i) -> map (\r -> (extends_ray (show i) r, i)) s) stars in - map fst (rays \\ linked) - -correct :: Diagram -> Bool -correct d = free_rays d /= [] && (isJust $ Unification.solution (equations d)) - -actualise :: Diagram -> Maybe Star -actualise d = do - u <- Unification.solution (equations d) - pure $ Star (subst_rays u (free_rays d)) - -fusions :: Star -> Star -> [Star] -fusions (Star star1) (Star star2) = do - ray1 <- star1 - ray2 <- star2 - guard (ray1 `matchable_rays` ray2) - u <- maybeToList $ Unification.solution [(get_term ray1, get_term ray2)] - [Star (subst_rays u (delete ray1 star1 ++ delete ray2 star2))] - -{- ======================================== - Execution - ======================================== -} - -connect :: (Star, Int) -> (Star, Int) -> [Link] -connect (Star s1, i) (Star s2, j) = do - r1 <- s1 - r2 <- s2 - guard (r1 `matchable_rays` r2) - [Link ((r1, r2), i, j)] - -saturated :: Constellation -> Diagram -> Bool -saturated cs d = - let free = free_rays d in - let rs = rays cs in - free_rays d /= [] && - [(r1, r2) | r1<-free, r2<-rs, r1 `matchable_rays` r2] == [] - -shift_link :: Int -> Link -> Link -shift_link k (Link (e, i, j)) = Link (e, i+k, j+k) - -singleStep :: Constellation -> Diagram -> [Diagram] -singleStep (Const cs) d@(StarGraph (stars, links)) = - let cs' = mapInd (curry id) cs in - let stars' = mapInd (curry id) stars in - do - (s1, i) <- cs' - (s2, j) <- stars' - link <- connect (s1, 0) (s2, j+1) - guard (not $ already_linked link (map (shift_link 1) links)) - pure (StarGraph (s1:stars, link:map (shift_link 1) links)) - -allCorrectDiagrams :: Constellation -> [Diagram] -allCorrectDiagrams (Const []) = [] -allCorrectDiagrams (Const cs) = go [StarGraph ([cs!!0], [])] where - go (d : ds) = do - d : go (ds ++ filter correct (singleStep (Const cs) d)) - go [] = [] - -allCorrectSaturatedDiagrams :: Constellation -> [Diagram] -allCorrectSaturatedDiagrams cs = filter (saturated cs) $ allCorrectDiagrams cs - -execution :: Constellation -> Constellation -execution cs = Const (catMaybes $ map actualise (allCorrectSaturatedDiagrams cs)) - - -skeleton :: Constellation -> Constellation - - -deleteAt :: Int -> [a] -> [a] -deleteAt idx xs = lft ++ rgt - where (lft, (_:rgt)) = splitAt idx xs - -fusion :: (Star, Int) -> (Star, Int) -> [Star] -fusion (Star s1, i) (Star s2, j) = - let r1 = s1 !! i in - let r2 = s2 !! j in - case Unification.solution [(get_term r1, get_term r2)] of - Just u -> [Star (subst_rays u (deleteAt i s1 ++ deleteAt j s2))] - Nothing -> [] - -step :: Constellation -> [Star] -> [Star] -step (Const cs) stars = do - s1' <- cs - s2' <- stars - let s1 = get_star s1' - let s2 = get_star s2' - guard (s1 /= s2) - i <- [0..length s1 - 1] - j <- [0..length s2 - 1] - guard ((s1 !! i) `matchable_rays` (s2 !! j)) - fusion (s1', i) (s2', j) - -steps :: Int -> Constellation -> [Star] -> [Star] -steps 0 _ mem = mem -steps k cs mem = - let new = step cs mem in - if new == [] then mem else mem ++ steps (k-1) cs new - -exec :: Constellation -> Constellation -exec wcs@(Const cs) = Const (steps 0 wcs cs) diff --git a/haskell/Unification.hs b/haskell/Unification.hs deleted file mode 100644 index b386593..0000000 --- a/haskell/Unification.hs +++ /dev/null @@ -1,94 +0,0 @@ -module Unification where -import PrettyPrinter -import Data.List -import Data.Maybe -import Control.Arrow - -{- ======================================== - Definitions - ======================================== -} - -type Id = String -data Term = - Var Id - | Func Id [Term] - deriving Eq - -type Subst = [(Id, Term)] -type Equation = (Term, Term) - -instance Show Term where - show (Var x) = x - show (Func f []) = f - show (Func f xs) = f ++ "(" ++ (addcomma (map show xs)) ++ ")" - -instance Ord Term where - compare (Var x) (Var y) = compare x y - compare (Var _) (Func _ _) = LT - compare (Func _ _) (Var _) = GT - compare (Func f fs) (Func g gs) = - case compare f g of - EQ -> compare fs gs - LT -> LT - GT -> GT - -{- ======================================== - Predicates - ======================================== -} - -indom :: Id -> Subst -> Bool -indom x s = isJust $ lookup x s - -occurs :: Id -> Term -> Bool -occurs x (Var y) = (x==y) -occurs x (Func _ ts) = any (occurs x) ts - -{- ======================================== - Renaming - ======================================== -} - -extends_varname :: String -> Term -> Term -extends_varname e (Var x) = Var (x++e) -extends_varname e (Func f ts) = Func f (map (extends_varname e) ts) - -vars :: Term -> [Id] -vars (Var x) = [x] -vars (Func _ xs) = concat (map vars xs) - - {- ======================================== - Substitution - ======================================== -} - -apply :: Subst -> Id -> Term -apply ((y, t):s) x = if (x==y) then t else apply s x - -subst :: Subst -> Term -> Term -subst s (Var x) = if indom x s then (apply s x) else (Var x) -subst s (Func f ts) = Func f (map (subst s) ts) - -{- ======================================== - Unification - ======================================== -} - -solve' :: [Equation] -> Subst -> Maybe Subst -solve' [] s = Just s -solve' ((Var x, t):ps) s = if (Var x == t) then solve' ps s else elim x t ps s -solve' ((t, Var x):ps) s = elim x t ps s -solve' ((Func f fs, Func g gs):ps) s = - if (f == g) then solve' (zip fs gs ++ ps) s else Nothing - -elim :: Id -> Term -> [Equation] -> Subst -> Maybe Subst -elim x t ps s = - if occurs x t then Nothing - else let sigma_xy = subst [(x, t)] in - solve' (map (\(t1, t2) -> (sigma_xy t1, sigma_xy t2)) ps) - ((x,t):map (\(y,u) -> (y, sigma_xy u)) s) - -solution :: [Equation] -> Maybe Subst -solution p = solve' p [] - -solvable :: [Equation] -> Bool -solvable p = isJust (solution p) - -matchable :: Equation -> Bool -matchable p = isJust $ solution [(extends_varname "0" *** extends_varname "1") p] diff --git a/instructions.pdf b/instructions.pdf deleted file mode 100644 index a5362cb26d842c9c5fb618e569cc5049a85de595..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149244 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%0AkbUyUCL4K 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 ZM`w4(f4juQ%E`gW217zW|g#g!KRb diff --git a/lexer.ml b/lexer.ml new file mode 100644 index 0000000..bf256dd --- /dev/null +++ b/lexer.ml @@ -0,0 +1,212 @@ +# 1 "lexer.mll" + + open Parser + exception Eof + +# 7 "lexer.ml" +let __ocaml_lex_tables = { + Lexing.lex_base = + "\000\000\240\255\241\255\001\000\003\000\243\255\002\000\245\255\ + \246\255\247\255\248\255\249\255\250\255\251\255\252\255\253\255\ + \078\000\088\000\244\255"; + Lexing.lex_backtrk = + "\255\255\255\255\255\255\014\000\013\000\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \001\000\000\000\255\255"; + Lexing.lex_default = + "\255\255\000\000\000\000\255\255\255\255\000\000\255\255\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \255\255\255\255\000\000"; + Lexing.lex_trans = + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\004\000\002\000\002\000\004\000\003\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \004\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\ + \015\000\014\000\000\000\008\000\013\000\007\000\005\000\018\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \016\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\017\000\017\000\017\000\017\000\017\000\017\000\017\000\ + \017\000\017\000\017\000\017\000\017\000\017\000\017\000\017\000\ + \017\000\017\000\017\000\017\000\017\000\017\000\017\000\017\000\ + \017\000\017\000\017\000\012\000\000\000\011\000\000\000\000\000\ + \000\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \016\000\016\000\016\000\010\000\006\000\009\000\016\000\016\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \017\000\017\000\017\000\017\000\017\000\017\000\017\000\017\000\ + \017\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000"; + Lexing.lex_check = + "\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\000\000\000\000\003\000\004\000\000\000\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \000\000\255\255\255\255\004\000\255\255\255\255\255\255\255\255\ + \000\000\000\000\255\255\000\000\000\000\000\000\000\000\006\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\255\255\000\000\255\255\255\255\ + \255\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ + \000\000\000\000\000\000\000\000\000\000\000\000\016\000\016\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \017\000\017\000\017\000\017\000\017\000\017\000\017\000\017\000\ + \017\000\017\000\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\016\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\ + \016\000\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \000\000\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ + \255\255"; + Lexing.lex_base_code = + ""; + Lexing.lex_backtrk_code = + ""; + Lexing.lex_default_code = + ""; + Lexing.lex_trans_code = + ""; + Lexing.lex_check_code = + ""; + Lexing.lex_code = + ""; +} + +let rec read lexbuf = + __ocaml_lex_read_rec lexbuf 0 +and __ocaml_lex_read_rec lexbuf __ocaml_lex_state = + match Lexing.engine __ocaml_lex_tables __ocaml_lex_state lexbuf with + | 0 -> +# 12 "lexer.mll" + ( VAR (Lexing.lexeme lexbuf) ) +# 132 "lexer.ml" + + | 1 -> +# 13 "lexer.mll" + ( SYM (Lexing.lexeme lexbuf) ) +# 137 "lexer.ml" + + | 2 -> +# 14 "lexer.mll" + ( LEFT_PAR ) +# 142 "lexer.ml" + + | 3 -> +# 15 "lexer.mll" + ( RIGHT_PAR ) +# 147 "lexer.ml" + + | 4 -> +# 16 "lexer.mll" + ( COMMA ) +# 152 "lexer.ml" + + | 5 -> +# 17 "lexer.mll" + ( LEFT_BRACK ) +# 157 "lexer.ml" + + | 6 -> +# 18 "lexer.mll" + ( RIGHT_BRACK ) +# 162 "lexer.ml" + + | 7 -> +# 19 "lexer.mll" + ( LEFT_BRACE ) +# 167 "lexer.ml" + + | 8 -> +# 20 "lexer.mll" + ( RIGHT_BRACE ) +# 172 "lexer.ml" + + | 9 -> +# 21 "lexer.mll" + ( PLUS ) +# 177 "lexer.ml" + + | 10 -> +# 22 "lexer.mll" + ( MINUS ) +# 182 "lexer.ml" + + | 11 -> +# 23 "lexer.mll" + ( VDASH ) +# 187 "lexer.ml" + + | 12 -> +# 24 "lexer.mll" + ( DOT ) +# 192 "lexer.ml" + + | 13 -> +# 25 "lexer.mll" + ( read lexbuf ) +# 197 "lexer.ml" + + | 14 -> +# 26 "lexer.mll" + ( read lexbuf ) +# 202 "lexer.ml" + + | 15 -> +# 27 "lexer.mll" + ( exit 0 ) +# 207 "lexer.ml" + + | __ocaml_lex_state -> lexbuf.Lexing.refill_buff lexbuf; + __ocaml_lex_read_rec lexbuf __ocaml_lex_state + +;; + diff --git a/lexer.mll b/lexer.mll new file mode 100644 index 0000000..1295206 --- /dev/null +++ b/lexer.mll @@ -0,0 +1,27 @@ +{ + open Parser + exception Eof +} + +let var_id = ['A'-'Z'] ['0'-'9']* +let func_id = ['a'-'z' '0'-'9']+ +let space = [' ' '\t']+ +let newline = '\r' | '\n' | "\r\n" + +rule read = parse + | var_id { VAR (Lexing.lexeme lexbuf) } + | func_id { SYM (Lexing.lexeme lexbuf) } + | '(' { LEFT_PAR } + | ')' { RIGHT_PAR } + | ',' { COMMA } + | '[' { LEFT_BRACK } + | ']' { RIGHT_BRACK } + | '{' { LEFT_BRACE } + | '}' { RIGHT_BRACE } + | '+' { PLUS } + | '-' { MINUS } + | "|-" { VDASH } + | '.' { DOT } + | space { read lexbuf } + | newline { read lexbuf } + | eof { exit 0 } \ No newline at end of file diff --git a/loop.stellar b/loop.stellar new file mode 100644 index 0000000..4850064 --- /dev/null +++ b/loop.stellar @@ -0,0 +1 @@ +{ [-1(X), -2(X)] } |- { [+1(X), +2(X)] } \ No newline at end of file diff --git a/main.ml b/main.ml new file mode 100644 index 0000000..e32472b --- /dev/null +++ b/main.ml @@ -0,0 +1,136 @@ +open Stellar +open Parser +open Tools + +(* --------------------------------------- + Prompt + --------------------------------------- *) + +let welcome () = print_endline "Use 'help' for the list of commands." + +let tab = repeat_string "\t" + +let line = repeat_string "-" + +let commands_list () = + print_endline ("Command" ^ tab 4 ^ "Description (shortcut)"); + print_endline (line 70); + print_endline ("exit" ^ tab 4 ^ "Exits the program"); + print_endline ("exec -f " ^ tab 2 ^ "Executes the constellation defined in "); + print_endline ("exec " ^ tab 3 ^ "Executes the interaction space "); + print_endline ( + "intmode" ^ + tab 4 ^ + "Enables interactive mode with the empty constellation as initial constellation." + ); + print_endline ( + "intmode " ^ + tab 2 ^ + "Enables interactive mode with as initial constellation" + ); + print_endline ( + "intmode -f " ^ + tab 2 ^ + "Enables interactive mode with the constellation defined in as initial constellation" + ); + print_endline ( + "disable-loops" ^ + tab 2 ^ + "Forbid equations X=X which yields trivial loops" + ); + print_endline ( + "enable-loops" ^ + tab 2 ^ + "Allow equations X=X which yields trivial loops (default setting)" + ) + (* print_endline ( + "load as " ^ + tab 1 ^ + "Stores a constellation defined in as in the environement" + ); + print_endline ( + "store as " ^ + tab 1 ^ + "Stores a constellation defined in as in the environement" + ) *) + +let prompt () = print_string "> " + +let intmode_prompt cs = + print_endline ">>>>>>>>>> Interactive mode"; + print_endline "Type constellations and they will interact your initial constellation ('exit' to exit interactive mode)."; + print_endline (string_of_constellation cs) + +let rec intmode ?(withloops=true) cs = + prompt (); + let input = read_line () in + if input = "exit" then + print_endline "<<<<<<<<<< Exit interactive mode" + else + (try + let cs' = constc Lexer.read (Lexing.from_string input) in + let result = intexec ~withloops (cs, cs') in + print_endline (string_of_constellation result); + intmode result + with _ -> + print_endline "Syntax error. Please try again."; + intmode cs) + +let last_command : string option ref = ref None + +(* --------------------------------------- + Main function + --------------------------------------- *) + +let _ = + let withloops = ref true in + welcome (); + while true do + prompt (); + let input = read_line () in + begin match String.split_on_char ' ' input with + | ["exit"] -> exit 0 + | ["disable-loops"] -> + print_endline "Loops disabled."; withloops := false + | ["enable-loops"] -> + print_endline "Loops enabled."; withloops := true + | ["help"] -> commands_list () + | ["exec"; "-f"; filename] -> + begin try + let lexbuf = Lexing.from_channel (open_in filename) in + let cs = spacec Lexer.read lexbuf in + let result = intexec ~withloops:!withloops cs in + print_endline (string_of_constellation result) + with Sys_error f -> print_endline f + end + | "exec"::intspace -> + let lexbuf = Lexing.from_string (String.concat " " intspace) in + (try + let cs = spacec Lexer.read lexbuf in + let result = intexec ~withloops:!withloops cs in + print_endline (string_of_constellation result) + with _ -> print_endline "Syntax error. Please try again.") + (* | ["load"; filename; "as"; x] -> + let fchannel = open_in filename in + let lexbuf = Lexing.from_channel fchannel in + let cs = constc Lexer.read lexbuf in + env := (x, cs) :: (!env) *) + | ["intmode"; "-f"; filename] -> + (try + let lexbuf = Lexing.from_channel (open_in filename) in + let cs = constc Lexer.read lexbuf in + intmode_prompt cs; + intmode cs + with Sys_error f -> print_endline f) + | ["intmode"] -> + intmode_prompt []; + intmode [] + | "intmode"::intspace -> + let lexbuf = Lexing.from_string (String.concat " " intspace) in + let cs = constc Lexer.read lexbuf in + intmode_prompt cs; + intmode cs + | _ -> + print_endline "Invalid command. Please type 'help' for the list of commands." + end + done \ No newline at end of file diff --git a/mllcorrectness.stellar b/mllcorrectness.stellar new file mode 100644 index 0000000..cb8f98f --- /dev/null +++ b/mllcorrectness.stellar @@ -0,0 +1,3 @@ +{ [+5(l.X), +6(l.X)] + [+5(r.X), +6(r.X)] + [-5(l.X), -5(r.X), 5(X)] + [-6(l.X)] } +|- +{ [-6(r.X), 6(X)] } \ No newline at end of file diff --git a/mllcutelim.stellar b/mllcutelim.stellar new file mode 100644 index 0000000..b3965b5 --- /dev/null +++ b/mllcutelim.stellar @@ -0,0 +1,3 @@ +{ [+7(l.X), +7(r.X)] + [3(X), +8(l.X)] + [-7(X), -8(X)] } +|- +{ [+8(r.X), 6(X)] } \ No newline at end of file diff --git a/ocaml/Circuits.ml b/ocaml/Circuits.ml deleted file mode 100644 index 519a58a..0000000 --- a/ocaml/Circuits.ml +++ /dev/null @@ -1,107 +0,0 @@ -(* ============================================ - Boolean circuits - ============================================ *) - -(* _________ Types _________ *) - -type var = string -type id = int - -type op = - | CIn of int | COut | CShare - | CAnd | COr | CNeg - -type input = id -type output = id -type gate = input list * op * output list -type circuit = gate list - -(* _________ Getters _________ *) - -let get_node_info circ target = - let (ins, op, outs) = - List.hd (List.filter (fun (_, _, outs) -> List.mem target outs) circ) - in (ins, op, outs) - -let get_inputs circ node = - let (ins, _, _) = get_node_info circ node in ins - -let get_outputs circ node = - let (_, _, outs) = get_node_info circ node in outs - -let get_op circ node = - let (_, op, _) = get_node_info circ node in op - -(* extracts the two first inputs in a list of inputs *) -let twinhd = function - | [] -> failwith "Error extract_bin_ins: no input." - | h1::h2::t -> (h1, h2) - | _ -> failwith "Error extract_bin_ins: inputs do not match." - -(* _________ Evaluation _________ *) - -(* provides the boolean value of the node 'concl' in a circuit 'circ' *) -let rec value circ concl = - match get_op circ concl with - | CIn i -> i - | CShare | COut -> - let x = List.hd (get_inputs circ concl) in - value circ x - | CAnd -> - let (x, y) = twinhd (get_inputs circ concl) in - let vx = value circ x in - let vy = value circ y in - min vx vy - | COr -> - let (x, y) = twinhd (get_inputs circ concl) in - let vx = value circ x in - let vy = value circ y in - max vx vy - | CNeg -> - let x = List.hd (get_inputs circ concl) in - let vx = value circ x in - 1 - vx - -let rec eval (circ : circuit) : int = - let (_, _, concl) = - List.hd (List.filter (fun (_, o, _) -> o = COut) circ) - in value circ (List.hd concl) - -(* _________ Examples _________ *) - -let make_gate ins op outs : gate = (ins, op, outs) -let make_input value outs : gate = ([], CIn value, outs) - -let make_and_circ x y : circuit = [ - make_input x [0]; - make_input y [1]; - make_gate [0;1] CAnd [2]; - make_gate [2] COut [3] -] - -let make_or_circ x y : circuit = [ - make_input x [0]; - make_input y [1]; - make_gate [0;1] COr [2]; - make_gate [2] COut [3] -] - -let make_neg_circ x : circuit = [ - make_input x [0]; - make_gate [0] CNeg [1]; - make_gate [1] COut [2] -] - -(* corresponds to the excluded middle x v ~x *) -let make_em_circ x : circuit = [ - make_input x [0]; - make_gate [0] CShare [1;2]; - make_gate [1] CNeg [3]; - make_gate [3;2] COr [4]; - make_gate [4] COut [5] -] - -let c1 = List.map eval [make_and_circ 0 0; make_and_circ 0 1; make_and_circ 1 0; make_and_circ 1 1] -let c2 = List.map eval [make_or_circ 0 0; make_or_circ 0 1; make_or_circ 1 0; make_or_circ 1 1] -let c3 = List.map eval [make_neg_circ 0; make_neg_circ 1] -let c4 = List.map eval [make_em_circ 0; make_em_circ 1] \ No newline at end of file diff --git a/ocaml/FSA.ml b/ocaml/FSA.ml deleted file mode 100644 index f7ab843..0000000 --- a/ocaml/FSA.ml +++ /dev/null @@ -1,32 +0,0 @@ -(* ============================================ - Finite State Automata - ============================================ *) - -type id = int - -type state = id -type initial_state = state -type final_state = state -type fa_transition = state * char * state -type fautomata = initial_state * (fa_transition list) * final_state list - -let accepts ((qi, ts, qf) : fautomata) (w : char list) = - let rec head q (read : char list) = - match read with - | [] -> List.mem q qf - | c::w -> - let (_, _, qnext) = - List.hd (List.filter (fun (qs, c', qt) -> qs=q && c=c') ts) - in head qnext w - in head qi w - -(* _________ Examples _________ *) - -let even_ones : fautomata = ( - 0, - [ - (0, '1', 1); - (1, '1', 0) - ], - [0] -) \ No newline at end of file diff --git a/ocaml/Resolution.ml b/ocaml/Resolution.ml deleted file mode 100644 index a62d6ca..0000000 --- a/ocaml/Resolution.ml +++ /dev/null @@ -1,250 +0,0 @@ -open Unification - -(* ======================================== - Definitions - ======================================== *) - -type pol = Pos | Neg | Npol -type ray = Var of id | Func of (id * pol * ray list) -(* alternative ray definition using terms *) -(* type ray = PR of id * pol * ray | NR of term *) -type star = ray list -type constellation = star list -type graph = (int * int) * (ray * ray) list - -(* token is a couple of a family number and a star number in the constellation *) -type token = int * int -type process = token list - -(* List monad *) -let return x = [x] (*plongement dans la monade de liste*) -let (>>=) xs k = List.flatten (List.map k xs) -let guard c x = if c then return x else [] - -(* ======================================== - Useful functions - ======================================== *) - -let make_const_pol pol c = Func (c, pol, []) -let make_const c = make_const_pol Npol c - - -(* Takes a list and remove doubles from it *) -let remove_double list = - List.fold_left (fun l a -> if not(List.mem a l) then (a::l) else l) [] list - -(* Convert a pol and an id to a string, adding + or - before the id *) -let pol_to_string pol id = - if pol = Pos then "+" ^ id - else if pol = Neg then "-" ^ id - else id - -(* Convert a ray (which is polarized) to a term (which isn't)*) -let rec ray_to_term r = - match r with - | Var id -> (Var(id) : term) - | Func(id, pol, raylist) -> (Func(pol_to_string pol id, List.map ray_to_term raylist) : term) - -(* Invert polarization of a pol*) -let inv_pol pol = - if pol = Pos then Neg - else if pol = Neg then Pos - else pol - -(* Invert the polarization of a ray to allow an easier Unification writing *) -let rec inv_pol_ray ray = - match ray with - | Func(id, pol, raylist) -> Func(id, inv_pol pol, List.map inv_pol_ray raylist) - | _ -> ray - -(* Checks if a ray is polarised *) -let rec is_polarised r = - match r with - | Var id -> false - | Func(_, p, r) -> (p <> Npol) || (List.fold_left (fun acc b -> (is_polarised b) || acc) false r) - -(* Checks if two rays are dual, meaning that after inverting polarization of one ray, the two rays can be unified *) -let dual_check r1 r2 = - if (is_polarised r1 && is_polarised r2) then - (solve [(extends_varname (ray_to_term (inv_pol_ray r1)) "0"), (extends_varname ((ray_to_term r2)) "1")] []) - else None - -(* Create an index for a constellation *) -let index_constellation const = - List.combine (List.init (List.length const) (fun a -> a)) const - -(* apply_ray applies a substitution to a var of a ray*) -let apply_ray id sub = - let (_,s) = try List.find (fun (a,_) -> a = id ) sub with Not_found -> (id,Var(id)) in (s :ray) - -(* substit_ray applies all possible substition from an environment to a ray *) -let rec substit_ray ray sub = - match ray with - | Var id -> apply_ray id sub - | Func(f, p, tl) -> Func(f, p, List.map (fun a -> substit_ray a sub) tl) - -(* substit_star applies all possible substition from an environment to a star *) -let substit_star star sub = - List.map (fun a -> substit_ray a sub) star - -(* substit_const applies all possible substition from an environment to a constellation *) -let substit_const const sub = - List.map (fun a -> substit_star a sub) const - -(* extends_varname adds suffix to all var names of a ray *) -let rec extends_varname_ray t ext = - match t with - | Var id -> Var(id ^ ext) - | Func(f, p, tl) -> Func(f, p, List.map (fun a -> extends_varname_ray a ext) tl) - -(* extends_varname adds suffix to all var names of a star *) -let extends_varname_star const ext = - List.map (fun a -> extends_varname_ray a ext) const - -(* extends_varname adds suffix to all var names of a constellation based on each star number after being indexed *) -let extends_varname_const const = - List.map (fun (i,a) -> extends_varname_star a (string_of_int i)) (index_constellation const) - -(* convert a term to a ray *) -let rec term_to_ray (term : term) = - match term with - | Var id -> (Var(id) : ray) - | Func(f, r) -> Func(f, Npol, List.map (fun a -> term_to_ray a) r) - -(* convert a star to a string*) -let rec star_to_string star = - match star with - | [] -> "" - | h::t -> term_to_string (ray_to_term h) ^ "\n" ^ (star_to_string t) - -(*print a star*) -let print_star star = - print_string (star_to_string star) - -(*convert a constellation to a string*) -let rec const_to_string const = - match const with - | [] -> "" - | h::t -> (star_to_string h) ^ "---------- \n" ^ (const_to_string t) - -(*print a constellation*) -let print_const const = - print_string (const_to_string const) - -(* ======================================== - Constellation graph - ======================================== *) - -(* Makes a dgraph from a constellation *) -let dgraph const = - let indexed_const = index_constellation const in - indexed_const >>= fun (i, il) -> - indexed_const >>= fun (j, jl) -> - il >>= fun r1 -> - jl >>= fun r2 -> - guard (j >= i) ( let uni = dual_check r1 r2 in - if Option.is_some uni then [((i,j),(r1,r2))] - else []) - -(* Convert a link to a string to be printable *) -let link_to_string dg = - let rec aux dgl = - match dgl with - | [] -> "" - | ((i,j),(r1, r2))::[] -> ("(" ^ string_of_int i ^ ", " ^ string_of_int j ^ ")" ^ "," ^ "(" ^ term_to_string (ray_to_term r1) ^ ", " ^ term_to_string (ray_to_term r2) ^ ")") - | ((i,j),(r1, r2))::t -> ("(" ^ string_of_int i ^ ", " ^ string_of_int j ^ ")" ^ "," ^ "(" ^ term_to_string (ray_to_term r1) ^ ", " ^ term_to_string (ray_to_term r2) ^ ")") ^ "+" ^ (aux t) - in aux dg ;; - -(* Convert an equation list (which is a link without the index) to a string *) -let eq_to_string eq = - let rec aux dgl = - match dgl with - | [] -> "" - | ((r1, r2))::[] -> ("(" ^ term_to_string (ray_to_term r1) ^ " = " ^ term_to_string (ray_to_term r2) ^ ")") - | ((r1, r2))::t -> ("(" ^ term_to_string (ray_to_term r1) ^ " = " ^ term_to_string (ray_to_term r2) ^ ")") ^ "\n" ^ (aux t) - in aux eq;; - -(* print an equation list*) -let print_eq eq = - print_string (eq_to_string eq) - -(* remove empty list from a dgraph *) -let clean_dgraph g = - List.filter (fun a -> a <> []) g - -(* Print a dgraph *) -let print_dgraph dg = - let rec aux dgl = - match dgl with - | [] -> "" - | h::[] -> (link_to_string h) - | h::t -> (link_to_string h) ^ "\n" ^ aux t - in print_string (aux (clean_dgraph dg));; - - (* get a star using its number in the list from a constellation *) -let get_star const i = - List.nth const i - -(* Takes a constellation, a ray and a (ray,ray) list and extracts rays from stars number i (respectively j) that are not ri (respectively rj) when ri (respectively rj) isn't in the prob list *) -let star_filter const ((i, j),(ri,rj)) prob = - let (prob_a, prob_b) = List.split prob in - (if List.mem ri prob_a then [] - else (List.filter (fun a -> a <> ri) (get_star const i)) - )@( - if List.mem rj prob_b then [] - else (List.filter (fun a -> a <> rj) (get_star const j)) - ) - -(* convert the (ray,ray) list part of a link to an equation, converting its rays to terms *) -let link_to_eq prob = - List.map (fun (ra, rb) -> (ray_to_term (inv_pol_ray ra)), ray_to_term rb) prob - -(* removes rays from prob from the star *) -let star_postfilter star prob = - let (prob_a, prob_b) = List.split prob in - List.filter (fun a -> not(List.mem a prob_a) && not(List.mem a prob_b )) star - -(* takes a token, a graph and a constellation and returns the list of tokens to check next and a list of solvable equation *) -let divide_token (fam, n_star) toklist graph const prob fstar = - let links = List.filter (fun ((i, _),(_, _)) -> i = n_star) graph in - let rec aux l tokl prob_aux star_aux = - match l with - [] -> Some (tokl,prob_aux,star_aux,fam) - | ((i, j),(ri,rj))::tl -> - if fam > (List.length prob_aux) || prob_aux = [] then (* We check if the family number is the same as the number of equations lists in prob. If it's superior, we add a new list in prob instead of filling the first equation list because it means we're treating a new family *) - if Option.is_some (dual_check ri rj) then - aux tl ((fam, j)::tokl) ([(ri, rj)]::prob_aux) ( (( star_filter const ((i, j),(ri,rj)) [] ))::star_aux ) - else None - else - if Option.is_some (solve (link_to_eq ((ri, rj)::(List.hd(*nth*) prob_aux (*fam*)))) []) then (* We made sure prob_aux head would not be empty*) - - aux tl ((fam, j)::tokl) (((ri, rj)::(List.hd prob_aux))::(List.tl prob_aux)) ( (( star_filter const ((i, j),(ri,rj)) (List.hd prob_aux) )@(List.hd star_aux))::(List.tl star_aux) ) (*We use List.hd because the current family we're working on should be the current first*) - else - None - in if links = [] then Some (toklist,prob,fstar,fam) - else aux links toklist prob fstar - -(* should be deterministic exec, graph shouldn't be empty, takes a constellation and a list of stars that are gonna be beginning points *) -(* Start_star_list, the second argument, should not be empty*) -let exec const start_star_list = - let const_ext = extends_varname_const const in - let graph = List.flatten (clean_dgraph (dgraph const_ext)) in - let max_fam = List.length start_star_list in - let rec aux (toklist,prob,star,current_fam) = (*toklist is a list of tokens (int of family number and the number of a star), prob is the current list of equations, current_fam is the current family number *) - begin match toklist with - | [] -> - if current_fam = max_fam-1 then star,prob - else aux ([(current_fam+1, List.nth start_star_list (current_fam+1))], prob, star, current_fam+1) - | h::t -> aux (Option.get (divide_token h t graph const_ext prob star )) - end - in if start_star_list = [] then - failwith "star_star_list is empty" - else - let i = List.hd start_star_list - in let (constf, prob_tmp) = aux ([(0,i)],[],[],0) - in let probf = List.rev prob_tmp - in let indexed_final_const = index_constellation constf - in List.map (fun (fam_star, a) -> - let fam_prob = List.nth probf fam_star - in let substit_list = (List.map (fun (i,b) -> (i,term_to_ray b)) (Option.get (solve (link_to_eq fam_prob) []))) - in substit_star (remove_double (star_postfilter a fam_prob)) substit_list) indexed_final_const \ No newline at end of file diff --git a/ocaml/StellarCircuits.ml b/ocaml/StellarCircuits.ml deleted file mode 100644 index 1bb36c4..0000000 --- a/ocaml/StellarCircuits.ml +++ /dev/null @@ -1,55 +0,0 @@ -open Circuits -open Resolution -(* ============================================ - Stellar Circuits - ============================================ *) - -let port pol i v = Func ("c"^(string_of_int i), pol, v) -let inport i x = port Neg i [Var x] -let outport i x = port Pos i [Var x] - -let call_cneg pol arg res = Func ("neg", pol, [arg; res]) -let call_cand pol arg1 arg2 res = Func ("and", pol, [arg1; arg2; res]) -let call_cor pol arg1 arg2 res = Func ("or", pol, [arg1; arg2; res]) - -let star_of_gate circ (ins, op, outs) = - match op with - | CIn i -> [port Pos (List.hd outs) [make_const (string_of_int i)]] - | COut -> [inport (List.hd ins) "r"; Var "r"] - | CShare -> - let (o1, o2) = twinhd outs in - [inport (List.hd ins) "x"; outport o1 "x"; outport o2 "x"] - | CNeg -> [ - inport (List.hd ins) "x"; - call_cneg Neg (Var "x") (Var "r"); - outport (List.hd outs) "r" - ] - | CAnd -> - let (i1, i2) = twinhd ins in [ - inport i1 "x"; - inport i2 "y"; - call_cand Neg (Var "x") (Var "y") (Var "r"); - outport (List.hd outs) "r" - ] - | COr -> - let (i1, i2) = twinhd ins in [ - inport i1 "x"; - inport i2 "y"; - call_cor Neg (Var "x") (Var "y") (Var "r"); - outport (List.hd outs) "r" - ] - -let const_of_circuit (circ : circuit) = List.map (star_of_gate circ) circ - -let prop_logic : constellation = [ - [call_cneg Pos (make_const "0") (make_const "1")]; - [call_cneg Pos (make_const "1") (make_const "0")]; - [call_cand Pos (make_const "0") (make_const "0") (make_const "0")]; - [call_cand Pos (make_const "0") (make_const "1") (make_const "0")]; - [call_cand Pos (make_const "1") (make_const "0") (make_const "0")]; - [call_cand Pos (make_const "1") (make_const "1") (make_const "1")]; - [call_cor Pos (make_const "0") (make_const "0") (make_const "0")]; - [call_cor Pos (make_const "0") (make_const "1") (make_const "1")]; - [call_cor Pos (make_const "1") (make_const "0") (make_const "1")]; - [call_cor Pos (make_const "1") (make_const "1") (make_const "1")] -] \ No newline at end of file diff --git a/ocaml/StellarFSA.ml b/ocaml/StellarFSA.ml deleted file mode 100644 index 9954635..0000000 --- a/ocaml/StellarFSA.ml +++ /dev/null @@ -1,15 +0,0 @@ -open Resolution -open FSA - -(* ============================================ - Stellar Automata - ============================================ *) - -let dot x y = Func ("·", Npol, [x; y]) - -let const_of_word (w : char list) = - let rec aux = function - | [] -> Func ("", Npol, []) - | c::w -> - dot (Func (String.make 1 c, Npol, [])) (aux w) - in [Func ("i", Pos, [aux w])] \ No newline at end of file diff --git a/ocaml/Unification.ml b/ocaml/Unification.ml deleted file mode 100644 index 9f6f1a3..0000000 --- a/ocaml/Unification.ml +++ /dev/null @@ -1,92 +0,0 @@ -open List -(* ======================================== - Definitions - ======================================== *) - -type id = string -type term = Var of id | Func of (id * term list) - -type subst = id * term list -type equation = term * term - -(* convert a term to a string *) -let rec term_to_string t = - match t with - | Var id -> id - | Func(f, []) -> f - | Func(f, tl) -> f ^ "(" ^ - let rec aux2 vl = - match vl with - | [] -> "" - | h::[] -> term_to_string h - | h::t -> (term_to_string h) ^ "," ^ (aux2 t) - in (aux2 tl) ^ ")" - -let print_term t = - print_string (term_to_string t) - -(* Compare two terms *) -let rec compare_term t1 t2 = - match t1, t2 with - | Var(id1), Var(id2) -> String.compare id1 id2 - | Var(_), Func(_,_) -> -1 - | Func(_,_), Var(_) -> 1 - | Func(f, fs), Func(g, gs) -> let comp = String.compare f g in if comp > 0 then 1 - else if comp < 0 then -1 - else List.compare compare_term fs gs - -(* Look if there's a var to be substituted in the term in the substitution environment *) -let rec indom t sl = - match t with - | Var id -> List.exists (fun (a,_) -> a = id ) sl - | Func(_, tl) -> List.exists (fun a -> indom a sl) tl - -(* occurs checks if given var is in term *) -let rec occurs id t = - match t with - | Var i -> i = id - | Func(_, tl) -> List.exists (fun a -> occurs id a) tl - - -(* extends_varname adds suffix to all var names of a term *) -let rec extends_varname t ext = - match t with - | Var id -> Var(id ^ ext) - | Func(f, tl) -> Func(f, List.map (fun a -> extends_varname a ext) tl) - - -(* vars gives a list of all vars in a term *) -let rec vars t = - match t with - | Var id -> [id] - | Func(_, tl) -> List.fold_left (fun a b -> (vars b)@a) [] tl - - (* ======================================== - Substitution - ======================================== *) - -(* apply applies a substitution to a var *) -let apply id sub = let (_,s) = try List.find (fun (a,_) -> a = id ) sub with Not_found -> (id,Var(id)) in s - -(* subst applies all possible substition from an environment to a term *) -let rec substit trm sub = - match trm with - | Var id -> apply id sub - | Func(f,tl) -> Func(f,List.map (fun a -> substit a sub) tl) - - (* ======================================== - Unification - ======================================== *) - -(* Solves an equation list by returning solution list *) -let rec solve eq sub = - match eq with - | [] -> Some sub - | (Var(x), term)::t -> if Var(x) = term then (solve t sub) else (elim x term t sub) (* If x = x it's a useless equation *) - | (term, Var(x))::t -> (elim x term t sub) (*It's useless to check if term = Var(x) because it would be the same case as above *) - | (Func(f, fs), Func(g, gs))::t -> if f = g then (solve ((List.combine fs gs)@t) sub) else (*failwith (Printf.sprintf "f=%s g=%s" f g)*) None (* If f and g are not equal, the equation can't be solved *) - -and elim id term eq sub = - if occurs id term then (*failwith (Printf.sprintf "id=%s is in term" id)*) None (* If that's the case, we would have something like x = f(x) which can't be solved *) - else let sigma_xy = [(id, term)] in - solve (List.map (fun (a,b) -> (substit a sigma_xy, substit b sigma_xy)) eq) ((List.map (fun (i, t) -> (i, substit t sigma_xy)) sub)@sigma_xy) (* We apply the sigma_xy substitution to the equations and the solution list and we add it to the solution list *) diff --git a/ocaml/main.ml b/ocaml/main.ml deleted file mode 100644 index d742ef5..0000000 --- a/ocaml/main.ml +++ /dev/null @@ -1,49 +0,0 @@ -open Resolution -open Circuits -open StellarCircuits - - (* ======================================== - Tests - ======================================== *) - -(* _________ Tests on Resolution _________ *) -let y = Var("y") -let x = Var("x") -let z = Var("z") -let r = Var("r") -let zero = make_const "0" -let s x = Func("s", Npol, [x]) -let add p x y z = Func("add", p, [x;y;z]) - -(* Convert int to term *) -let rec enat i = - if i = 0 then zero else s (enat (i-1)) - -(* makes the constellation corresponding to an addition *) -let make_const_add n m = - [[add Pos zero y y]; [add Neg x y z; add Pos (s x) y (s z)]; [add Neg (enat n) (enat m) r; r]] - -let constellation = make_const_add 1 3 ;; - -print_dgraph (dgraph constellation) ;; - -(* simple determinist constellation test*) -let test = [ [Func("e", Neg, [x]); x] ; [Func("e", Pos, [Func("d", Npol, [y])]) ; Func("e", Npol, [x]) ] ] ;; -print_dgraph (dgraph test);; -exec test ;; - -(* _________ Tests on exec using Stellar Circuits _________ *) - -(* Constellation of excluded middle without boolean doors *) -let excl_mid_no_prop = (const_of_circuit (make_em_circ 1));; - -(* Constellation of excluded middle with boolean doors *) -let excl_mid_prop = ((const_of_circuit (make_em_circ 1))@[[Func("or", Pos, [Func("0", Npol, []); Func("1", Npol, []); Func("1", Npol, [])])];[Func("neg",Pos, [Func("1", Npol, []); Func("0", Npol, [])])]]);; - -let exec_exmid_noprop = exec excl_mid_no_prop [0];; -(* should return 1*) -let exec_exmid_prop = exec excl_mid_prop [0];; - -print_const exec_exmid_prop;; - -let test_fam = excl_mid_prop@test \ No newline at end of file diff --git a/parser.ml b/parser.ml new file mode 100644 index 0000000..2bd1a70 --- /dev/null +++ b/parser.ml @@ -0,0 +1,666 @@ + +module MenhirBasics = struct + + exception Error + + let _eRR = + fun _s -> + raise Error + + type token = + | VDASH + | VAR of ( +# 5 "parser.mly" + (string) +# 16 "parser.ml" + ) + | SYM of ( +# 6 "parser.mly" + (string) +# 21 "parser.ml" + ) + | RIGHT_PAR + | RIGHT_BRACK + | RIGHT_BRACE + | PLUS + | MINUS + | LEFT_PAR + | LEFT_BRACK + | LEFT_BRACE + | DOT + | COMMA + +end + +include MenhirBasics + +type ('s, 'r) _menhir_state = + | MenhirState00 : ('s, _menhir_box_constc) _menhir_state + (** State 00. + Stack shape : . + Start symbol: constc. *) + + | MenhirState01 : (('s, 'r) _menhir_cell1_LEFT_BRACE, 'r) _menhir_state + (** State 01. + Stack shape : LEFT_BRACE. + Start symbol: . *) + + | MenhirState02 : (('s, 'r) _menhir_cell1_LEFT_BRACK, 'r) _menhir_state + (** State 02. + Stack shape : LEFT_BRACK. + Start symbol: . *) + + | MenhirState10 : (('s, 'r) _menhir_cell1_symc, 'r) _menhir_state + (** State 10. + Stack shape : symc. + Start symbol: . *) + + | MenhirState14 : (('s, 'r) _menhir_cell1_rayc, 'r) _menhir_state + (** State 14. + Stack shape : rayc. + Start symbol: . *) + + | MenhirState16 : (('s, 'r) _menhir_cell1_rayc, 'r) _menhir_state + (** State 16. + Stack shape : rayc. + Start symbol: . *) + + | MenhirState22 : (('s, 'r) _menhir_cell1_starc, 'r) _menhir_state + (** State 22. + Stack shape : starc. + Start symbol: . *) + + | MenhirState28 : ('s, _menhir_box_spacec) _menhir_state + (** State 28. + Stack shape : . + Start symbol: spacec. *) + + | MenhirState29 : (('s, _menhir_box_spacec) _menhir_cell1_LEFT_BRACE, _menhir_box_spacec) _menhir_state + (** State 29. + Stack shape : LEFT_BRACE. + Start symbol: spacec. *) + + | MenhirState34 : (('s, _menhir_box_spacec) _menhir_cell1_constc, _menhir_box_spacec) _menhir_state + (** State 34. + Stack shape : constc. + Start symbol: spacec. *) + + +and ('s, 'r) _menhir_cell1_constc = + | MenhirCell1_constc of 's * ('s, 'r) _menhir_state * (Stellar.constellation) + +and ('s, 'r) _menhir_cell1_rayc = + | MenhirCell1_rayc of 's * ('s, 'r) _menhir_state * (Stellar.StellarRays.term) + +and ('s, 'r) _menhir_cell1_starc = + | MenhirCell1_starc of 's * ('s, 'r) _menhir_state * (Stellar.star) + +and ('s, 'r) _menhir_cell1_symc = + | MenhirCell1_symc of 's * ('s, 'r) _menhir_state * (Stellar.StellarSig.idfunc) + +and ('s, 'r) _menhir_cell1_LEFT_BRACE = + | MenhirCell1_LEFT_BRACE of 's * ('s, 'r) _menhir_state + +and ('s, 'r) _menhir_cell1_LEFT_BRACK = + | MenhirCell1_LEFT_BRACK of 's * ('s, 'r) _menhir_state + +and _menhir_box_spacec = + | MenhirBox_spacec of (Stellar.constellation * Stellar.constellation) [@@unboxed] + +and _menhir_box_constc = + | MenhirBox_constc of (Stellar.constellation) [@@unboxed] + +let _menhir_action_02 = + fun xs -> + let cs = +# 229 "" + ( xs ) +# 119 "parser.ml" + in + ( +# 22 "parser.mly" + ( cs ) +# 124 "parser.ml" + : (Stellar.constellation)) + +let _menhir_action_03 = + fun () -> + ( +# 139 "" + ( [] ) +# 132 "parser.ml" + : (Stellar.star)) + +let _menhir_action_04 = + fun x -> + ( +# 141 "" + ( x ) +# 140 "parser.ml" + : (Stellar.star)) + +let _menhir_action_05 = + fun () -> + ( +# 139 "" + ( [] ) +# 148 "parser.ml" + : (Stellar.constellation)) + +let _menhir_action_06 = + fun x -> + ( +# 141 "" + ( x ) +# 156 "parser.ml" + : (Stellar.constellation)) + +let _menhir_action_07 = + fun x -> + ( +# 33 "parser.mly" + ( Stellar.to_var x ) +# 164 "parser.ml" + : (Stellar.StellarRays.term)) + +let _menhir_action_08 = + fun r1 r2 -> + ( +# 34 "parser.mly" + ( Stellar.to_func ((Stellar.Null, "."), [r1; r2]) ) +# 172 "parser.ml" + : (Stellar.StellarRays.term)) + +let _menhir_action_09 = + fun pf ts -> + ( +# 36 "parser.mly" + ( Stellar.to_func (pf, ts) ) +# 180 "parser.ml" + : (Stellar.StellarRays.term)) + +let _menhir_action_10 = + fun pf -> + ( +# 37 "parser.mly" + ( Stellar.to_func (pf, []) ) +# 188 "parser.ml" + : (Stellar.StellarRays.term)) + +let _menhir_action_11 = + fun x -> + ( +# 238 "" + ( [ x ] ) +# 196 "parser.ml" + : (Stellar.star)) + +let _menhir_action_12 = + fun x xs -> + ( +# 240 "" + ( x :: xs ) +# 204 "parser.ml" + : (Stellar.star)) + +let _menhir_action_13 = + fun x -> + ( +# 238 "" + ( [ x ] ) +# 212 "parser.ml" + : (Stellar.constellation)) + +let _menhir_action_14 = + fun x xs -> + ( +# 240 "" + ( x :: xs ) +# 220 "parser.ml" + : (Stellar.constellation)) + +let _menhir_action_15 = + fun cs space -> + ( +# 19 "parser.mly" + ( (cs, space) ) +# 228 "parser.ml" + : (Stellar.constellation * Stellar.constellation)) + +let _menhir_action_16 = + fun xs -> + let rs = +# 229 "" + ( xs ) +# 236 "parser.ml" + in + ( +# 25 "parser.mly" + ( rs ) +# 241 "parser.ml" + : (Stellar.star)) + +let _menhir_action_17 = + fun f p -> + ( +# 28 "parser.mly" + ( (Pos, f) ) +# 249 "parser.ml" + : (Stellar.StellarSig.idfunc)) + +let _menhir_action_18 = + fun f p -> + ( +# 29 "parser.mly" + ( (Neg, f) ) +# 257 "parser.ml" + : (Stellar.StellarSig.idfunc)) + +let _menhir_action_19 = + fun f -> + ( +# 30 "parser.mly" + ( (Stellar.Null, f) ) +# 265 "parser.ml" + : (Stellar.StellarSig.idfunc)) + +let _menhir_print_token : token -> string = + fun _tok -> + match _tok with + | COMMA -> + "COMMA" + | DOT -> + "DOT" + | LEFT_BRACE -> + "LEFT_BRACE" + | LEFT_BRACK -> + "LEFT_BRACK" + | LEFT_PAR -> + "LEFT_PAR" + | MINUS -> + "MINUS" + | PLUS -> + "PLUS" + | RIGHT_BRACE -> + "RIGHT_BRACE" + | RIGHT_BRACK -> + "RIGHT_BRACK" + | RIGHT_PAR -> + "RIGHT_PAR" + | SYM _ -> + "SYM" + | VAR _ -> + "VAR" + | VDASH -> + "VDASH" + +let _menhir_fail : unit -> 'a = + fun () -> + Printf.eprintf "Internal failure -- please contact the parser generator's developers.\n%!"; + assert false + +include struct + + [@@@ocaml.warning "-4-37-39"] + + let rec _menhir_run_35 : type ttv_stack. (ttv_stack, _menhir_box_spacec) _menhir_cell1_constc -> _ -> _menhir_box_spacec = + fun _menhir_stack _v -> + let MenhirCell1_constc (_menhir_stack, _, cs) = _menhir_stack in + let space = _v in + let _v = _menhir_action_15 cs space in + MenhirBox_spacec _v + + let rec _menhir_run_27 : type ttv_stack. ttv_stack -> _ -> _menhir_box_constc = + fun _menhir_stack _v -> + MenhirBox_constc _v + + let rec _menhir_run_01 : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s -> + let _menhir_stack = MenhirCell1_LEFT_BRACE (_menhir_stack, _menhir_s) in + let _tok = _menhir_lexer _menhir_lexbuf in + match (_tok : MenhirBasics.token) with + | LEFT_BRACK -> + _menhir_run_02 _menhir_stack _menhir_lexbuf _menhir_lexer MenhirState01 + | RIGHT_BRACE -> + let _v = _menhir_action_05 () in + _menhir_run_25 _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok + | _ -> + _eRR () + + and _menhir_run_02 : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s -> + let _menhir_stack = MenhirCell1_LEFT_BRACK (_menhir_stack, _menhir_s) in + let _menhir_s = MenhirState02 in + let _tok = _menhir_lexer _menhir_lexbuf in + match (_tok : MenhirBasics.token) with + | VAR _v -> + _menhir_run_03 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s + | SYM _v -> + _menhir_run_04 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s + | PLUS -> + _menhir_run_05 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | MINUS -> + _menhir_run_07 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | RIGHT_BRACK -> + let _v = _menhir_action_03 () in + _menhir_goto_loption_separated_nonempty_list_COMMA_rayc__ _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok + | _ -> + _eRR () + + and _menhir_run_03 : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s -> + let _tok = _menhir_lexer _menhir_lexbuf in + let x = _v in + let _v = _menhir_action_07 x in + _menhir_goto_rayc _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + + and _menhir_goto_rayc : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok -> + match _menhir_s with + | MenhirState14 -> + _menhir_run_15 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | MenhirState02 -> + _menhir_run_13 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | MenhirState16 -> + _menhir_run_13 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | MenhirState10 -> + _menhir_run_13 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | _ -> + _menhir_fail () + + and _menhir_run_15 : type ttv_stack ttv_result. ((ttv_stack, ttv_result) _menhir_cell1_rayc as 'stack) -> _ -> _ -> _ -> ('stack, ttv_result) _menhir_state -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok -> + match (_tok : MenhirBasics.token) with + | DOT -> + let _menhir_stack = MenhirCell1_rayc (_menhir_stack, _menhir_s, _v) in + _menhir_run_14 _menhir_stack _menhir_lexbuf _menhir_lexer + | COMMA | RIGHT_BRACK | RIGHT_PAR -> + let MenhirCell1_rayc (_menhir_stack, _menhir_s, r1) = _menhir_stack in + let r2 = _v in + let _v = _menhir_action_08 r1 r2 in + _menhir_goto_rayc _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | _ -> + _eRR () + + and _menhir_run_14 : type ttv_stack ttv_result. (ttv_stack, ttv_result) _menhir_cell1_rayc -> _ -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer -> + let _menhir_s = MenhirState14 in + let _tok = _menhir_lexer _menhir_lexbuf in + match (_tok : MenhirBasics.token) with + | VAR _v -> + _menhir_run_03 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s + | SYM _v -> + _menhir_run_04 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s + | PLUS -> + _menhir_run_05 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | MINUS -> + _menhir_run_07 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | _ -> + _eRR () + + and _menhir_run_04 : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s -> + let _tok = _menhir_lexer _menhir_lexbuf in + let f = _v in + let _v = _menhir_action_19 f in + _menhir_goto_symc _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + + and _menhir_goto_symc : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok -> + match (_tok : MenhirBasics.token) with + | LEFT_PAR -> + let _menhir_stack = MenhirCell1_symc (_menhir_stack, _menhir_s, _v) in + let _menhir_s = MenhirState10 in + let _tok = _menhir_lexer _menhir_lexbuf in + (match (_tok : MenhirBasics.token) with + | VAR _v -> + _menhir_run_03 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s + | SYM _v -> + _menhir_run_04 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s + | PLUS -> + _menhir_run_05 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | MINUS -> + _menhir_run_07 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | _ -> + _eRR ()) + | COMMA | DOT | RIGHT_BRACK | RIGHT_PAR -> + let pf = _v in + let _v = _menhir_action_10 pf in + _menhir_goto_rayc _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | _ -> + _eRR () + + and _menhir_run_05 : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s -> + let _tok = _menhir_lexer _menhir_lexbuf in + match (_tok : MenhirBasics.token) with + | SYM _v -> + let _tok = _menhir_lexer _menhir_lexbuf in + let (f, p) = (_v, ()) in + let _v = _menhir_action_17 f p in + _menhir_goto_symc _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | _ -> + _eRR () + + and _menhir_run_07 : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s -> + let _tok = _menhir_lexer _menhir_lexbuf in + match (_tok : MenhirBasics.token) with + | SYM _v -> + let _tok = _menhir_lexer _menhir_lexbuf in + let (f, p) = (_v, ()) in + let _v = _menhir_action_18 f p in + _menhir_goto_symc _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | _ -> + _eRR () + + and _menhir_run_13 : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok -> + match (_tok : MenhirBasics.token) with + | DOT -> + let _menhir_stack = MenhirCell1_rayc (_menhir_stack, _menhir_s, _v) in + _menhir_run_14 _menhir_stack _menhir_lexbuf _menhir_lexer + | COMMA -> + let _menhir_stack = MenhirCell1_rayc (_menhir_stack, _menhir_s, _v) in + let _menhir_s = MenhirState16 in + let _tok = _menhir_lexer _menhir_lexbuf in + (match (_tok : MenhirBasics.token) with + | VAR _v -> + _menhir_run_03 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s + | SYM _v -> + _menhir_run_04 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s + | PLUS -> + _menhir_run_05 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | MINUS -> + _menhir_run_07 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | _ -> + _eRR ()) + | RIGHT_BRACK | RIGHT_PAR -> + let x = _v in + let _v = _menhir_action_11 x in + _menhir_goto_separated_nonempty_list_COMMA_rayc_ _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | _ -> + _eRR () + + and _menhir_goto_separated_nonempty_list_COMMA_rayc_ : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok -> + match _menhir_s with + | MenhirState02 -> + _menhir_run_18 _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok + | MenhirState16 -> + _menhir_run_17 _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok + | MenhirState10 -> + _menhir_run_11 _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok + | _ -> + _menhir_fail () + + and _menhir_run_18 : type ttv_stack ttv_result. (ttv_stack, ttv_result) _menhir_cell1_LEFT_BRACK -> _ -> _ -> _ -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok -> + let x = _v in + let _v = _menhir_action_04 x in + _menhir_goto_loption_separated_nonempty_list_COMMA_rayc__ _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok + + and _menhir_goto_loption_separated_nonempty_list_COMMA_rayc__ : type ttv_stack ttv_result. (ttv_stack, ttv_result) _menhir_cell1_LEFT_BRACK -> _ -> _ -> _ -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok -> + match (_tok : MenhirBasics.token) with + | RIGHT_BRACK -> + let _tok = _menhir_lexer _menhir_lexbuf in + let MenhirCell1_LEFT_BRACK (_menhir_stack, _menhir_s) = _menhir_stack in + let xs = _v in + let _v = _menhir_action_16 xs in + (match (_tok : MenhirBasics.token) with + | PLUS -> + let _menhir_stack = MenhirCell1_starc (_menhir_stack, _menhir_s, _v) in + let _menhir_s = MenhirState22 in + let _tok = _menhir_lexer _menhir_lexbuf in + (match (_tok : MenhirBasics.token) with + | LEFT_BRACK -> + _menhir_run_02 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | _ -> + _eRR ()) + | RIGHT_BRACE -> + let x = _v in + let _v = _menhir_action_13 x in + _menhir_goto_separated_nonempty_list_PLUS_starc_ _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | _ -> + _eRR ()) + | _ -> + _eRR () + + and _menhir_goto_separated_nonempty_list_PLUS_starc_ : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok -> + match _menhir_s with + | MenhirState29 -> + _menhir_run_24 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | MenhirState01 -> + _menhir_run_24 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | MenhirState22 -> + _menhir_run_23 _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok + | _ -> + _menhir_fail () + + and _menhir_run_24 : type ttv_stack ttv_result. ((ttv_stack, ttv_result) _menhir_cell1_LEFT_BRACE as 'stack) -> _ -> _ -> _ -> ('stack, ttv_result) _menhir_state -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok -> + let x = _v in + let _v = _menhir_action_06 x in + _menhir_goto_loption_separated_nonempty_list_PLUS_starc__ _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + + and _menhir_goto_loption_separated_nonempty_list_PLUS_starc__ : type ttv_stack ttv_result. ((ttv_stack, ttv_result) _menhir_cell1_LEFT_BRACE as 'stack) -> _ -> _ -> _ -> ('stack, ttv_result) _menhir_state -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok -> + match _menhir_s with + | MenhirState29 -> + _menhir_run_30 _menhir_stack _menhir_lexbuf _menhir_lexer _v + | MenhirState01 -> + _menhir_run_25 _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok + | _ -> + _menhir_fail () + + and _menhir_run_30 : type ttv_stack. (ttv_stack, _menhir_box_spacec) _menhir_cell1_LEFT_BRACE -> _ -> _ -> _ -> _menhir_box_spacec = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v -> + let _tok = _menhir_lexer _menhir_lexbuf in + let MenhirCell1_LEFT_BRACE (_menhir_stack, _menhir_s) = _menhir_stack in + let xs = _v in + let _v = _menhir_action_02 xs in + _menhir_goto_constc _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + + and _menhir_goto_constc : type ttv_stack ttv_result. ttv_stack -> _ -> _ -> _ -> (ttv_stack, ttv_result) _menhir_state -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok -> + match _menhir_s with + | MenhirState34 -> + _menhir_run_35 _menhir_stack _v + | MenhirState28 -> + _menhir_run_33 _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | MenhirState00 -> + _menhir_run_27 _menhir_stack _v + | _ -> + _menhir_fail () + + and _menhir_run_33 : type ttv_stack. ttv_stack -> _ -> _ -> _ -> (ttv_stack, _menhir_box_spacec) _menhir_state -> _ -> _menhir_box_spacec = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok -> + let _menhir_stack = MenhirCell1_constc (_menhir_stack, _menhir_s, _v) in + match (_tok : MenhirBasics.token) with + | VDASH -> + let _menhir_s = MenhirState34 in + let _tok = _menhir_lexer _menhir_lexbuf in + (match (_tok : MenhirBasics.token) with + | LEFT_BRACE -> + _menhir_run_01 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | _ -> + _eRR ()) + | _ -> + _eRR () + + and _menhir_run_25 : type ttv_stack ttv_result. (ttv_stack, ttv_result) _menhir_cell1_LEFT_BRACE -> _ -> _ -> _ -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok -> + let MenhirCell1_LEFT_BRACE (_menhir_stack, _menhir_s) = _menhir_stack in + let xs = _v in + let _v = _menhir_action_02 xs in + _menhir_goto_constc _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + + and _menhir_run_23 : type ttv_stack ttv_result. (ttv_stack, ttv_result) _menhir_cell1_starc -> _ -> _ -> _ -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok -> + let MenhirCell1_starc (_menhir_stack, _menhir_s, x) = _menhir_stack in + let xs = _v in + let _v = _menhir_action_14 x xs in + _menhir_goto_separated_nonempty_list_PLUS_starc_ _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + + and _menhir_run_17 : type ttv_stack ttv_result. (ttv_stack, ttv_result) _menhir_cell1_rayc -> _ -> _ -> _ -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok -> + let MenhirCell1_rayc (_menhir_stack, _menhir_s, x) = _menhir_stack in + let xs = _v in + let _v = _menhir_action_12 x xs in + _menhir_goto_separated_nonempty_list_COMMA_rayc_ _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + + and _menhir_run_11 : type ttv_stack ttv_result. (ttv_stack, ttv_result) _menhir_cell1_symc -> _ -> _ -> _ -> _ -> ttv_result = + fun _menhir_stack _menhir_lexbuf _menhir_lexer _v _tok -> + match (_tok : MenhirBasics.token) with + | RIGHT_PAR -> + let _tok = _menhir_lexer _menhir_lexbuf in + let MenhirCell1_symc (_menhir_stack, _menhir_s, pf) = _menhir_stack in + let ts = _v in + let _v = _menhir_action_09 pf ts in + _menhir_goto_rayc _menhir_stack _menhir_lexbuf _menhir_lexer _v _menhir_s _tok + | _ -> + _eRR () + + let rec _menhir_run_00 : type ttv_stack. ttv_stack -> _ -> _ -> _menhir_box_constc = + fun _menhir_stack _menhir_lexbuf _menhir_lexer -> + let _menhir_s = MenhirState00 in + let _tok = _menhir_lexer _menhir_lexbuf in + match (_tok : MenhirBasics.token) with + | LEFT_BRACE -> + _menhir_run_01 _menhir_stack _menhir_lexbuf _menhir_lexer _menhir_s + | _ -> + _eRR () + + let rec _menhir_run_28 : type ttv_stack. ttv_stack -> _ -> _ -> _menhir_box_spacec = + fun _menhir_stack _menhir_lexbuf _menhir_lexer -> + let _tok = _menhir_lexer _menhir_lexbuf in + match (_tok : MenhirBasics.token) with + | LEFT_BRACE -> + let _menhir_stack = MenhirCell1_LEFT_BRACE (_menhir_stack, MenhirState28) in + let _tok = _menhir_lexer _menhir_lexbuf in + (match (_tok : MenhirBasics.token) with + | LEFT_BRACK -> + _menhir_run_02 _menhir_stack _menhir_lexbuf _menhir_lexer MenhirState29 + | RIGHT_BRACE -> + let _v = _menhir_action_05 () in + _menhir_run_30 _menhir_stack _menhir_lexbuf _menhir_lexer _v + | _ -> + _eRR ()) + | _ -> + _eRR () + +end + +let spacec = + fun _menhir_lexer _menhir_lexbuf -> + let _menhir_stack = () in + let MenhirBox_spacec v = _menhir_run_28 _menhir_stack _menhir_lexbuf _menhir_lexer in + v + +let constc = + fun _menhir_lexer _menhir_lexbuf -> + let _menhir_stack = () in + let MenhirBox_constc v = _menhir_run_00 _menhir_stack _menhir_lexbuf _menhir_lexer in + v diff --git a/parser.mli b/parser.mli new file mode 100644 index 0000000..0732848 --- /dev/null +++ b/parser.mli @@ -0,0 +1,27 @@ + +(* The type of tokens. *) + +type token = + | VDASH + | VAR of (string) + | SYM of (string) + | RIGHT_PAR + | RIGHT_BRACK + | RIGHT_BRACE + | PLUS + | MINUS + | LEFT_PAR + | LEFT_BRACK + | LEFT_BRACE + | DOT + | COMMA + +(* This exception is raised by the monolithic API functions. *) + +exception Error + +(* The monolithic API. *) + +val spacec: (Lexing.lexbuf -> token) -> Lexing.lexbuf -> (Stellar.constellation * Stellar.constellation) + +val constc: (Lexing.lexbuf -> token) -> Lexing.lexbuf -> (Stellar.constellation) diff --git a/parser.mly b/parser.mly new file mode 100644 index 0000000..1c6f2f7 --- /dev/null +++ b/parser.mly @@ -0,0 +1,37 @@ +%token COMMA +%token LEFT_BRACK RIGHT_BRACK +%token LEFT_PAR RIGHT_PAR +%token LEFT_BRACE RIGHT_BRACE +%token VAR +%token SYM +%token PLUS MINUS +%token DOT +%token VDASH + +%right DOT + +%start spacec +%start constc + +%% + +spacec: +| cs = constc; VDASH; space = constc { (cs, space) } + +constc: +| LEFT_BRACE; cs = separated_list(PLUS, starc); RIGHT_BRACE { cs } + +starc: +| LEFT_BRACK; rs = separated_list(COMMA, rayc); RIGHT_BRACK { rs } + +symc: +| p = PLUS; f = SYM { (Pos, f) } +| p = MINUS; f = SYM { (Neg, f) } +| f = SYM { (Stellar.Null, f) } + +rayc: +| x = VAR { Stellar.to_var x } +| r1 = rayc; DOT; r2 = rayc { Stellar.to_func ((Stellar.Null, "."), [r1; r2]) } +| pf = symc; LEFT_PAR; ts = separated_nonempty_list(COMMA, rayc); RIGHT_PAR + { Stellar.to_func (pf, ts) } +| pf = symc { Stellar.to_func (pf, []) } \ No newline at end of file diff --git a/prolog.stellar b/prolog.stellar new file mode 100644 index 0000000..3ee59fe --- /dev/null +++ b/prolog.stellar @@ -0,0 +1,8 @@ +{ + [+add(0, Y, Y)] + + [-add(X, Y, Z), +add(s(X), Y, s(Z))] +} +|- +{ + [-add(s(s(0)), s(s(0)), R), R] +} \ No newline at end of file diff --git a/stellar.ml b/stellar.ml new file mode 100644 index 0000000..c17e6ec --- /dev/null +++ b/stellar.ml @@ -0,0 +1,123 @@ +type polarity = Pos | Neg | Null + +let string_of_polarity = function + | Pos -> "+" + | Neg -> "-" + | Null -> "" + +let string_of_polsym (p, f) = (string_of_polarity p) ^ f + +module StellarSig = struct + type idvar = string + type idfunc = polarity * string + let concat = (^) + let compatible f g = + match f, g with + | (Pos, f), (Neg, g) + | (Neg, f), (Pos, g) when f = g -> true + | (Null, f), (Null, g) when f = g -> true + | _ -> false + let string_of_idfunc = string_of_polsym +end + +module StellarRays = Unification.Make(StellarSig) + +open StellarSig +open StellarRays +open Tools + +(* --------------------------------------- + Stars and Constellations + --------------------------------------- *) + +type ray = term +type star = ray list +type constellation = star list + +let to_var x = Var x +let to_func (pf, ts) = Func (pf, ts) + +let pos f = (Pos, f) +let neg f = (Neg, f) +let null f = (Null, f) + +let pfunc f ts = Func (pos f, ts) +let nfunc f ts = Func (neg f, ts) +let func f ts = Func (null f, ts) +let var x = Var x +let pconst f = pfunc f [] +let nconst f = nfunc f [] +let const f = func f [] + +let rec is_polarised r : bool = + let aux = (function + | (Pos, _) | (Neg, _) -> true + | (Null, _) -> false) + in exists_term_func aux r + +(* --------------------------------------- + Display + --------------------------------------- *) + +let rec string_of_list printer sep = function + | [] -> "" + | [x] -> printer x + | h::t -> + (printer h) ^ sep ^ (string_of_list printer sep t) + +let rec string_of_ray = function + | Var x -> x + | Func (pf, []) -> string_of_polsym pf + | Func ((Null, "."), [r1; r2]) -> + (string_of_ray r1) ^ " · " ^ (string_of_ray r2) + | Func (pf, ts) -> string_of_polsym pf ^ + "(" ^ (string_of_list string_of_ray ", " ts) ^ ")" + +let string_of_subst sub = + "{" ^ + (List.fold_left ( + fun acc (x, r) -> x ^ "->" ^ (string_of_ray r) + ) "" sub) ^ + "}" + +let string_of_star s = "[" ^ (string_of_list string_of_ray ", " s) ^ "]" + +let string_of_constellation cs = + if cs = [] then "{}" else string_of_list string_of_star " + " cs + +let string_of_intspace (cs, space) = + (string_of_constellation cs) ^ " |- " ^ (string_of_constellation space) + +(* --------------------------------------- + Interactive execution + --------------------------------------- *) + +let raymatcher ?(withloops=true) r r' : substitution option = + if is_polarised r && is_polarised r' then + solution ~withloops [(r, r')] + else + None + +let interaction ?(withloops=true) (s : star) i j (cs : constellation) : constellation = + cs >>= fun i' s' -> + let s = List.map (extends_vars i) s in + let s' = List.map (extends_vars i') s' in + s' >>= fun j' r' -> + match raymatcher ~withloops (List.nth s j) r' with + | None -> [] + | Some sub -> + let s1 = without j s in + let s2 = without j' s' in + return (List.map (subst sub) (s1@s2)) + +let intspace ?(withloops=true) cs space : constellation = + List.flatten ( + space >>= fun i s -> + s >>= fun j _ -> + return (interaction ~withloops s i j (cs@space)) + ) + +let rec intexec ?(withloops=true) (cs, space) : constellation = + let result = intspace ~withloops cs space in + if result = [] then space + else intexec ~withloops (cs, result) \ No newline at end of file diff --git a/tools.ml b/tools.ml new file mode 100644 index 0000000..2196aad --- /dev/null +++ b/tools.ml @@ -0,0 +1,21 @@ +(* --------------------------------------- + Few useful functions + --------------------------------------- *) + +let lift_pairl f (x, y) = (f x, y) +let lift_pairr f (x, y) = (x, f y) +let lift_pair f p = lift_pairr f (lift_pairl f p) + +let rec repeat_string s n = if n=0 then "" else s ^ repeat_string s (n-1) + +let foldi_left f acc l = + snd (List.fold_left (fun (i, acc') x -> (i+1, f i acc' x)) (0, acc) l) + +let without i l = foldi_left (fun j acc x -> if i=j then acc else acc@[x]) [] l + +(* --------------------------------------- + List monad (with index) + --------------------------------------- *) + +let return x = [x] +let (>>=) l f = List.flatten (List.mapi f l) \ No newline at end of file diff --git a/unification.ml b/unification.ml new file mode 100644 index 0000000..3fd60dd --- /dev/null +++ b/unification.ml @@ -0,0 +1,85 @@ +open Tools + +module type Signature = sig + type idvar + type idfunc + val concat : idvar -> string -> idvar + val compatible : idfunc -> idfunc -> bool + val string_of_idfunc : idfunc -> string +end + +(* --------------------------------------- + Elementary definitions + --------------------------------------- *) + +module Make (Sig : Signature) = struct + +type term = + | Var of Sig.idvar + | Func of (Sig.idfunc * term list) + +type substitution = (Sig.idvar * term) list +type equation = term * term +type problem = equation list + +let rec fold_term fnode fbase acc = function + | Var x -> fbase x acc + | Func (f, ts) -> + let acc' = fnode f acc in + List.fold_left (fold_term fnode fbase) acc' ts + +let rec map_term fnode fbase = function + | Var x -> fbase x + | Func (g, ts) -> + Func (fnode g, List.map (map_term fnode fbase) ts) + +let skip = fun _ acc -> acc + +let exists_term_vars p t = fold_term skip (fun y acc -> p y || acc) false t +let all_term_vars p t = fold_term skip (fun y acc -> p y && acc) true t +let exists_term_func p t = fold_term (fun y acc -> p y || acc) skip false t +let all_term_func p t = fold_term (fun y acc -> p y && acc) skip true t + +let occurs x t = exists_term_vars (fun y -> x=y) t + +let extends_vars (i : int) = + map_term (fun x -> x) (fun x -> Var (Sig.concat x (string_of_int i))) + +let vars t = fold_term skip List.cons [] t + +let apply sub x = try List.assoc x sub with Not_found -> Var x +let rec subst sub = map_term (fun x -> x) (apply sub) + +(* --------------------------------------- + Unification algorithm + --------------------------------------- *) + +let rec solve ?(withloops=true) sub : problem -> substitution option = function + | [] -> Some sub + (* Clear *) + | (Var x, Var y)::pbs when x = y -> + if withloops then solve ~withloops sub pbs else None + (* Orient + Replace *) + | (Var x, t)::pbs | (t, Var x)::pbs -> elim ~withloops x t pbs sub + (* Open *) + | (Func (f, ts), Func (g, us))::pbs when Sig.compatible f g -> + begin try solve ~withloops sub ((List.combine ts us)@pbs) + with Invalid_argument _ -> + failwith ( + "Unification error on symbols " ^ + (Sig.string_of_idfunc f) ^ + " and " ^ + (Sig.string_of_idfunc g)) + end + | _ -> None +(* Replace *) +and elim ?(withloops=true) x t pbs sub : substitution option = + if occurs x t then None (* Circularity *) + else + let new_prob = List.map (lift_pair (subst [(x, t)])) pbs in + let new_sub = (x, t) :: List.map (lift_pairr (subst [(x, t)])) sub in + solve ~withloops new_sub new_prob + +let solution ?(withloops=true) : problem -> substitution option = solve ~withloops [] + +end \ No newline at end of file