4 changes: 4 additions & 0 deletions CHANGES.md
@@ -1,3 +1,7 @@
Clafer Version 0.4.2.1 released on Oct 19, 2015

* Fixed Haddock build, updated README, fixed a test case.

Clafer Version 0.4.2 released on Oct 16, 2015

* [Release](https://github.com/gsdlab/clafer/pull/74)
Expand Down
72 changes: 45 additions & 27 deletions README.md
Expand Up @@ -3,7 +3,8 @@

# Clafer, the Language

v0.4.2
v0.4.2.1


[Clafer](http://clafer.org) is a general-purpose lightweight structural modeling language developed by
[GSD Lab](http://gsd.uwaterloo.ca/), [University of Waterloo](http://uwaterloo.ca), and
Expand Down Expand Up @@ -32,7 +33,7 @@ This is also known as *Concept Modeling* or *Ontology Modeling*.
# Clafer, the Compiler

Clafer compiler provides a reference implementation of Clafer, the language.
It translates models in Clafer to other formats (e.g., Alloy, JSON, Python, JS, HTML, DOT) to allow for reasoning and processing with existing tools (Alloy Analyzer, Choco3, and Z3 SMT solver, GraphViz).
It translates models in Clafer to other formats (e.g., Alloy, JSON, JS, HTML, DOT) to allow for reasoning and processing with existing tools (Alloy Analyzer, Choco3, and GraphViz).

Currently, the compiler is used by

Expand Down Expand Up @@ -66,15 +67,15 @@ Regardless of the installation method, the following are
Optional:

* [Java Platform (JDK)](http://www.oracle.com/technetwork/java/javase/downloads/index.html) v8+, 32bit on Windows, 64bit otherwise
* needed only for running Alloy validation
* only needed for running Alloy validation
* [Alloy4.2](http://alloy.mit.edu/alloy/download.html)
* needed only for Alloy output validation
* only needed for Alloy output validation
* [GraphViz](http://graphviz.org/)
* the program `dot` is needed only in the `html` mode for SVG graph generation

### Installation from binaries

Binary distributions of the release 0.4.2 of Clafer Tools for Windows, Mac, and Linux,
Binary distributions of the release 0.4.2.1 of Clafer Tools for Windows, Mac, and Linux,
can be downloaded from
[Clafer Tools - Binary Distributions](http://gsd.uwaterloo.ca/clafer-tools-binary-distributions).

Expand All @@ -83,34 +84,46 @@ can be downloaded from

### Installation from Hackage

Dependencies
Clafer is now available on [Hackage](http://hackage.haskell.org/package/clafer-0.4.2.1/) and it can be installed using either [`stack`](https://github.com/commercialhaskell/stack) or [`cabal-install`](https://hackage.haskell.org/package/cabal-install).

* [GHC](https://www.haskell.org/downloads) v7.10.*
#### Installation using `stack`

Clafer is now available on [Hackage](http://hackage.haskell.org/package/clafer-0.4.2/) and it can be installed using
Stack is the only requirement: no other Haskell tooling needs to be installed because stack will automatically install everything that's needed.

1. `cabal update`
2. `cabal install clafer`
3. on Windows `cd C:\Users\<user>\AppData\Roaming\cabal\i386-windows-ghc-7.10.2\clafer-0.4.2`
4. on Linux `ca ~/.cabal/share/x86_64-linux-ghc-7.10.2/clafer-0.4.2/`
5. to automatically download Alloy jars, execute
* `cd tools`
* `make`
1. [install `stack`](https://github.com/commercialhaskell/stack#how-to-install)
2. execute `stack install clafer`

#### Installation using `cabal-install`

Dependencies

* [GHC](https://www.haskell.org/downloads) >= 7.8.3. 7.10.2 is recommended,
* `cabal-install` >= 1.18, should be installed together with a GHC distribution,
* [alex](https://hackage.haskell.org/package/alex),
* [happy](https://hackage.haskell.org/package/happy).

1. Install GHC
2. `cabal update`
3. `cabal install alex happy`
4. `cabal install clafer`
5. on Windows `cd C:\Users\<user>\AppData\Roaming\cabal\i386-windows-ghc-7.10.2\clafer-0.4.2.1`
6. on Linux `ca ~/.cabal/share/x86_64-linux-ghc-7.10.2/clafer-0.4.2.1/`
7. to automatically download Alloy jars, execute
* `make alloy4.2.jar`,
* move `alloy4.2.jar` to the location of the clafer executable.

### Installation from the source code

Dependencies

* [GHC](https://www.haskell.org/downloads) v7.10.*
* [Alloy4.2](http://alloy.mit.edu/alloy/download.html)
* downloaded automatically during the build
* [`stack`](https://github.com/commercialhaskell/stack#how-to-install)
* [Git](http://git-scm.com/)

On Windows

* [MSYS2](http://msys2.sourceforge.net/)
* download MSYS2 installer
* in MSYS2 console, execute
* it is installed automatically by `stack`
* after building clafer, execute
* `pacman -Syu`
* `pacman -S make wget unzip diffutils`

Expand All @@ -124,13 +137,18 @@ Development versions from branches `develop` should work well together but this

#### Building

1. install the dependencies
2. open the command line terminal. On Windows, open MSYS2 terminal.
3. in some `<source directory>` of your choice, execute
1. in some `<source directory>` of your choice, execute
* `git clone git://github.com/gsdlab/clafer.git`
4. in `<source directory>/clafer`, execute
* `cabal update`
* `make init`
2. in `<source directory>/clafer`, execute `stack setup`. This will install all dependencies, build tools, and MSYS2 (on Windows).
3. first time only on Windows
* open `MinGW64 Shell` using `C:\Users\<user>\AppData\Local\Programs\stack\i386-windows\msys2-20150512\mingw64_shell.bat`
* update MSYS2 following the [update procedure](http://sourceforge.net/p/msys2/wiki/MSYS2%20installation/):
* `pacman -Sy`
* `pacman --needed -S bash pacman pacman-mirrors msys2-runtime`
* restart shell if the runtime was updated
* `pacman -Su`
* `pacman -S make wget unzip diffutils`
4. `cd <source directory>`
* `make`

### Installation
Expand All @@ -156,7 +174,7 @@ See [clafer-vim](https://github.com/wasowski/clafer-vim)
(As printed by `clafer --help`)

```
Clafer 0.4.2
Clafer 0.4.2.1
clafer [OPTIONS] [FILE]
Expand Down
6 changes: 3 additions & 3 deletions clafer.cabal
@@ -1,5 +1,5 @@
Name: clafer
Version: 0.4.2
Version: 0.4.2.1
Synopsis: Compiles Clafer models to other formats: Alloy, JavaScript, JSON, HTML, Dot.
Description: Clafer is a general purpose, lightweight, structural modeling language developed at GSD Lab, University of Waterloo, and MODELS group at IT University of Copenhagen. Lightweight modeling aims at improving the understanding of the problem domain in the early stages of software development and determining the requirements with fewer defects. Clafer's goal is to make modeling more accessible to a wider range of users and domains. The tool provides a reference language implementation. It translates models to other formats (e.g. Alloy, JavaScript, JSON) to allow for reasoning with existing tools.
Homepage: http://clafer.org
Expand Down Expand Up @@ -40,7 +40,7 @@ Executable clafer
, cmdargs >= 0.10.12
, split >= 0.2.2

, clafer == 0.4.2
, clafer == 0.4.2.1
other-modules: Paths_clafer

library
Expand Down Expand Up @@ -140,7 +140,7 @@ Test-Suite test-suite
, tasty-th >= 0.1.3
, transformers-compat >= 0.3 && < 0.5
, mtl-compat >= 0.2.1
, clafer == 0.4.2
, clafer == 0.4.2.1

ghc-options: -Wall

Expand Down
10 changes: 5 additions & 5 deletions src/Language/Clafer/Intermediate/ResolverInheritance.hs
Expand Up @@ -53,7 +53,7 @@ resolveNModule (imodule, genv') =
abstractClafers = filter _isAbstract $ bfsClafers $ toClafers unresolvedDecls
resolvedDecls <- mapM (resolveNElement abstractClafers) unresolvedDecls
let
relocatedDecls = relocateTopLevelAbstractToParents resolvedDecls -- |> Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> <|
relocatedDecls = relocateTopLevelAbstractToParents resolvedDecls -- F> Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> <F
uidClaferMap' = createUidIClaferMap imodule{_mDecls = relocatedDecls}
resolvedHierarchyDecls = map (resolveHierarchy uidClaferMap') relocatedDecls
resolvedHierarchiesIModule = imodule{_mDecls = resolvedHierarchyDecls}
Expand All @@ -67,7 +67,7 @@ resolveNClafer :: [IClafer] -> IClafer -> Resolve IClafer
resolveNClafer abstractClafers clafer =
do
(super', superIClafer') <- resolveNSuper abstractClafers $ _super clafer
-- |> Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> |>
-- F> Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> F>
let
parentUID' =
case superIClafer' of
Expand All @@ -76,7 +76,7 @@ resolveNClafer abstractClafers clafer =
then _parentUID superIClafer'' -- make clafer a sibling of the superIClafer'
else _parentUID clafer
Nothing -> _parentUID clafer
-- <| Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> <|
-- <F Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> <F
elements' <- mapM (resolveNElement abstractClafers) $ _elements clafer
return $ clafer {_super = super', _parentUID = parentUID', _elements = elements'}

Expand Down Expand Up @@ -312,7 +312,7 @@ resolveRedefinition (iModule, _) =
else ("Improperly nested clafer '" ++ i ++ "' on line " ++ show l ++ " column " ++ show c ++ "\n")
isImproper _ = ""

-- |> Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> |>
-- F> Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> F>
relocateTopLevelAbstractToParents :: [IElement] -> [IElement]
relocateTopLevelAbstractToParents originalElements =
let
Expand Down Expand Up @@ -342,4 +342,4 @@ relocateTopLevelAbstractToParents originalElements =
++ newChildren
in
targetElement & iClafer . elements .~ newElements
-- <| Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> <|
-- <F Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> <F
2 changes: 1 addition & 1 deletion stack.yaml
@@ -1,6 +1,6 @@
# for GHC-7.10.2
extra-deps: [ data-stringmap-1.0.1.1 ]
resolver: lts-3.9
resolver: lts-3.10

# for GHC-7.8.4
# extra-deps: [ data-stringmap-1.0.1.1, json-builder-0.3 ]
Expand Down
6 changes: 3 additions & 3 deletions test/positive/ACCDemo_attributedFeatureModels.cfr
@@ -1,4 +1,4 @@
//# OPTIONS --sg

abstract Feature
cost -> integer

Expand Down Expand Up @@ -48,8 +48,8 @@ abstract Car
[this.cost = 1]

total_cost -> integer = sum Feature.cost
total_comfort -> integer = sum ComfortFeature.cost
total_fuel -> integer = sum FuelFeature.cost
total_comfort -> integer = sum ComfortFeature.comfort
total_fuel -> integer = sum FuelFeature.fuel
//# FRAGMENT
aCar : Car
//# FRAGMENT
Expand Down
4 changes: 2 additions & 2 deletions test/regression/ACCDemo_attributedFeatureModels.als.reg
Expand Up @@ -32,8 +32,8 @@ abstract sig c0_Car
, r_c0_total_comfort : one c0_total_comfort
, r_c0_total_fuel : one c0_total_fuel }
{ (some this.@r_c0_total_cost) => (((this.@r_c0_total_cost).@c0_total_cost_ref) = (sum temp : (c0_Feature.@r_c0_cost) | temp.@c0_cost_ref))
(some this.@r_c0_total_comfort) => (((this.@r_c0_total_comfort).@c0_total_comfort_ref) = (sum temp : (c0_ComfortFeature.@r_c0_cost) | temp.@c0_cost_ref))
(some this.@r_c0_total_fuel) => (((this.@r_c0_total_fuel).@c0_total_fuel_ref) = (sum temp : (c0_FuelFeature.@r_c0_cost) | temp.@c0_cost_ref)) }
(some this.@r_c0_total_comfort) => (((this.@r_c0_total_comfort).@c0_total_comfort_ref) = (sum temp : (c0_ComfortFeature.@r_c0_comfort) | temp.@c0_comfort_ref))
(some this.@r_c0_total_fuel) => (((this.@r_c0_total_fuel).@c0_total_fuel_ref) = (sum temp : (c0_FuelFeature.@r_c0_fuel) | temp.@c0_fuel_ref)) }

sig c0_ABS extends c0_Feature
{}
Expand Down
2 changes: 1 addition & 1 deletion test/regression/ACCDemo_attributedFeatureModels.dot.reg
Expand Up @@ -11,7 +11,7 @@ edge [fontname=Sans fontsize=11];
"c0_ComfortFeature" -> "c0_Feature" [arrowhead=onormal constraint=true weight=100];
"c0_FuelFeature" [label="abstract FuelFeature : ComfortFeature" URL="#c0_FuelFeature" tooltip="abstract FuelFeature : ComfortFeature&#10; fuel -&gt; integer&#10;"];
"c0_FuelFeature" -> "c0_ComfortFeature" [arrowhead=onormal constraint=true weight=100];
"c0_Car" [label="abstract Car" URL="#c0_Car" tooltip="abstract Car&#10; ABS : Feature ?&#10; [ this.cost = 2 ]&#10; CC : FuelFeature ?&#10; [ this.fuel = 1 ]&#10; [ this.comfort = 3 ]&#10; [ this.cost = 4 ]&#10; ACC : FuelFeature ?&#10; [ this.fuel = 2 ]&#10; [ this.comfort = 6 ]&#10; [ this.cost = 3 ]&#10; [ FCA ]&#10; xor Transmission&#10; Automatic : FuelFeature&#10; [ this.fuel = 2 ]&#10; [ this.comfort = 2 ]&#10; [ this.cost = 3 ]&#10; Manual : FuelFeature&#10; [ this.fuel = 0 ]&#10; [ this.comfort = 1 ]&#10; [ this.cost = 2 ]&#10; FCA : FuelFeature ?&#10; [ this.fuel = 2 ]&#10; [ this.comfort = 4 ]&#10; [ this.cost = 5 ]&#10; xor Sensor&#10; Radar : Feature&#10; [ this.cost = 2 ]&#10; Lidar : Feature&#10; [ this.cost = 4 ]&#10; xor Alert&#10; Haptic : ComfortFeature&#10; [ this.comfort = 4 ]&#10; [ this.cost = 2 ]&#10; Audible : ComfortFeature&#10; [ this.comfort = 2 ]&#10; [ this.cost = 1 ]&#10; total_cost -&gt; integer = sum Feature.cost&#10; total_comfort -&gt; integer = sum ComfortFeature.cost&#10; total_fuel -&gt; integer = sum FuelFeature.cost&#10;"];
"c0_Car" [label="abstract Car" URL="#c0_Car" tooltip="abstract Car&#10; ABS : Feature ?&#10; [ this.cost = 2 ]&#10; CC : FuelFeature ?&#10; [ this.fuel = 1 ]&#10; [ this.comfort = 3 ]&#10; [ this.cost = 4 ]&#10; ACC : FuelFeature ?&#10; [ this.fuel = 2 ]&#10; [ this.comfort = 6 ]&#10; [ this.cost = 3 ]&#10; [ FCA ]&#10; xor Transmission&#10; Automatic : FuelFeature&#10; [ this.fuel = 2 ]&#10; [ this.comfort = 2 ]&#10; [ this.cost = 3 ]&#10; Manual : FuelFeature&#10; [ this.fuel = 0 ]&#10; [ this.comfort = 1 ]&#10; [ this.cost = 2 ]&#10; FCA : FuelFeature ?&#10; [ this.fuel = 2 ]&#10; [ this.comfort = 4 ]&#10; [ this.cost = 5 ]&#10; xor Sensor&#10; Radar : Feature&#10; [ this.cost = 2 ]&#10; Lidar : Feature&#10; [ this.cost = 4 ]&#10; xor Alert&#10; Haptic : ComfortFeature&#10; [ this.comfort = 4 ]&#10; [ this.cost = 2 ]&#10; Audible : ComfortFeature&#10; [ this.comfort = 2 ]&#10; [ this.cost = 1 ]&#10; total_cost -&gt; integer = sum Feature.cost&#10; total_comfort -&gt; integer = sum ComfortFeature.comfort&#10; total_fuel -&gt; integer = sum FuelFeature.fuel&#10;"];
"c0_Car" -> "c0_Feature" [arrowhead=vee arrowtail=diamond dir=both style=solid weight=10 color=gray arrowsize=0.6 minlen=2 penwidth=0.5 constraint=true];
"c0_Car" -> "c0_FuelFeature" [arrowhead=vee arrowtail=diamond dir=both style=solid weight=10 color=gray arrowsize=0.6 minlen=2 penwidth=0.5 constraint=true];
"c0_Car" -> "c0_FuelFeature" [arrowhead=vee arrowtail=diamond dir=both style=solid weight=10 color=gray arrowsize=0.6 minlen=2 penwidth=0.5 constraint=true];
Expand Down
4 changes: 2 additions & 2 deletions test/regression/ACCDemo_attributedFeatureModels.html.reg
Expand Up @@ -131,9 +131,9 @@ a[href$='Ambiguous name'] {color: yellow}
<div class="indent">
<span class="claferDecl" id="c0_total_cost">total_cost</span><span class="keyword"> -> </span><a href="#integer"><span class="reference">integer</span></a> = sum <a href="#c0_Feature"><span class="reference">Feature</span></a>.<a href="#c0_cost"><span class="reference">cost</span></a></div>
<div class="indent">
<span class="claferDecl" id="c0_total_comfort">total_comfort</span><span class="keyword"> -> </span><a href="#integer"><span class="reference">integer</span></a> = sum <a href="#c0_ComfortFeature"><span class="reference">ComfortFeature</span></a>.<a href="#c0_cost"><span class="reference">cost</span></a></div>
<span class="claferDecl" id="c0_total_comfort">total_comfort</span><span class="keyword"> -> </span><a href="#integer"><span class="reference">integer</span></a> = sum <a href="#c0_ComfortFeature"><span class="reference">ComfortFeature</span></a>.<a href="#c0_comfort"><span class="reference">comfort</span></a></div>
<div class="indent">
<span class="claferDecl" id="c0_total_fuel">total_fuel</span><span class="keyword"> -> </span><a href="#integer"><span class="reference">integer</span></a> = sum <a href="#c0_FuelFeature"><span class="reference">FuelFeature</span></a>.<a href="#c0_cost"><span class="reference">cost</span></a></div>
<span class="claferDecl" id="c0_total_fuel">total_fuel</span><span class="keyword"> -> </span><a href="#integer"><span class="reference">integer</span></a> = sum <a href="#c0_FuelFeature"><span class="reference">FuelFeature</span></a>.<a href="#c0_fuel"><span class="reference">fuel</span></a></div>
</div>

<!-- # FRAGMENT /-->
Expand Down
4 changes: 2 additions & 2 deletions test/regression/ACCDemo_attributedFeatureModels.js.reg
Expand Up @@ -34,8 +34,8 @@ c0_total_cost.refTo(Int);
c0_total_comfort.refTo(Int);
c0_total_fuel.refTo(Int);
c0_Car.addConstraint(implies(some(join($this(), c0_total_cost)), equal(joinRef(join($this(), c0_total_cost)), sum(join(global(c0_Feature), c0_cost)))));
c0_Car.addConstraint(implies(some(join($this(), c0_total_comfort)), equal(joinRef(join($this(), c0_total_comfort)), sum(join(global(c0_ComfortFeature), c0_cost)))));
c0_Car.addConstraint(implies(some(join($this(), c0_total_fuel)), equal(joinRef(join($this(), c0_total_fuel)), sum(join(global(c0_FuelFeature), c0_cost)))));
c0_Car.addConstraint(implies(some(join($this(), c0_total_comfort)), equal(joinRef(join($this(), c0_total_comfort)), sum(join(global(c0_ComfortFeature), c0_comfort)))));
c0_Car.addConstraint(implies(some(join($this(), c0_total_fuel)), equal(joinRef(join($this(), c0_total_fuel)), sum(join(global(c0_FuelFeature), c0_fuel)))));
c0_ABS.addConstraint(equal(joinRef(join($this(), c0_cost)), constant(2)));
c0_CC.addConstraint(equal(joinRef(join($this(), c0_fuel)), constant(1)));
c0_CC.addConstraint(equal(joinRef(join($this(), c0_comfort)), constant(3)));
Expand Down
4 changes: 2 additions & 2 deletions test/regression/ACCDemo_attributedFeatureModels.py.reg
Expand Up @@ -31,8 +31,8 @@ c0_total_cost.refTo("int");
c0_total_comfort.refTo("int");
c0_total_fuel.refTo("int");
c0_Car.addConstraint(implies(some(join($this(), c0_total_cost)), equal(joinRef(join($this(), c0_total_cost)), sum(join(glob(c0_Feature), c0_cost)))));
c0_Car.addConstraint(implies(some(join($this(), c0_total_comfort)), equal(joinRef(join($this(), c0_total_comfort)), sum(join(glob(c0_ComfortFeature), c0_cost)))));
c0_Car.addConstraint(implies(some(join($this(), c0_total_fuel)), equal(joinRef(join($this(), c0_total_fuel)), sum(join(glob(c0_FuelFeature), c0_cost)))));
c0_Car.addConstraint(implies(some(join($this(), c0_total_comfort)), equal(joinRef(join($this(), c0_total_comfort)), sum(join(glob(c0_ComfortFeature), c0_comfort)))));
c0_Car.addConstraint(implies(some(join($this(), c0_total_fuel)), equal(joinRef(join($this(), c0_total_fuel)), sum(join(glob(c0_FuelFeature), c0_fuel)))));
c0_ABS.addConstraint(equal(joinRef(join($this(), c0_cost)), constant(2)));
c0_CC.addConstraint(equal(joinRef(join($this(), c0_fuel)), constant(1)));
c0_CC.addConstraint(equal(joinRef(join($this(), c0_comfort)), constant(3)));
Expand Down