packages feed

cpsa 2.0.2 → 2.0.3

raw patch · 40 files changed

+611/−82 lines, 40 files

Files

ChangeLog view
@@ -1,5 +1,24 @@-2010-03-11  John D. Ramsdell  <ramsdell@gootoo>+2010-03-30  John D. Ramsdell  <ramsdell@mitre.org> +	* cpsa.cabal (Version): Tagged as version 2.0.3.++	* src/CPSA/Lib/Cohort.hs (useEncryptionFirstOrder): Added switch+	to determine critical message search order.++	* src/CPSA/Lib/Strand.hs (skelNons, skelUniques): Use inheritRnon,+	and inheritRunique for inherited origination assumptions.++2010-03-27  John D. Ramsdell  <ramsdell@mitre.org>++	* src/pp.pl: Added an SWI-Prolog version of the pretty printer in+	CPSA.Lib.Pretty.++	* src/cpsa.pl: Added an SWI-Prolog version of the CPSA specific+	pretty printer in CPSA.Lib.Printer and support for skeleton+	transformations.++2010-03-11  John D. Ramsdell  <ramsdell@mitre.org>+ 	* cpsa.cabal (Version): Tagged as version 2.0.2.  	* src/CPSA/Graph/Loader.hs (itrace): When computing the trace of@@ -9,6 +28,10 @@  	* cpsa.cabal (Version): Tagged as version 2.0.1. +2010-03-10  John D. Ramsdell  <ramsdell@mitre.org>++	* src/cpsa.el: Added Emacs support for skeleton transformations.+ 2010-03-07  John D. Ramsdell  <ramsdell@mitre.org>  	* src/CPSA/Basic/Algebra.hs (rootName):  Improved renaming@@ -211,7 +234,7 @@ 	Two functions were added for printing terms is the operation 	field.  These functions extend the display context as needed. -2009-08-05  John D. Ramsdell  <ramsdell@gootoo>+2009-08-05  John D. Ramsdell  <ramsdell@mitre.org>  	* cpsa.cabal (Version): Tagged as version 1.4.8. 
NEWS view
@@ -1,5 +1,19 @@ CPSA NEWS -- history of user-visible changes. +* Changes in version 2.0.3++** Generalization bug fixed+A bug associated with origination assumption forgetting has been+fixed.++** SWI Prolog tools added+Tools that allows CPSA to be manipulated in Prolog are in the src+directory.  The tools include a pretty printer that uses the same+algorithm as is used in the Haskell pretty printer.++** Cabal description improved+An expanded description of CPSA has been added to its cabal file.+ * Changes in version 2.0.2  ** Better message terms in graphs
cpsa.cabal view
@@ -1,19 +1,42 @@ Name:			cpsa-Version:		2.0.2+Version:		2.0.3 Maintainer:		ramsdell@mitre.org Cabal-Version:		>= 1.2 License:		BSD3 License-File:		license.txt Synopsis:		Symbolic cryptographic protocol analyzer-Description:            The Cryptographic Protocol Shapes Analyzer-                        (CPSA) attempts to enumerate all essentially-                        different executions possible for a-                        cryptographic protocol.  We call them the-                        shapes of the protocol.  Naturally occurring-                        protocols have only finitely many, indeed very-                        few shapes.  Authentication and secrecy-                        properties are easy to determine from them, as-                        are attacks and anomalies.+Description:+  The Cryptographic Protocol Shapes Analyzer (CPSA) attempts to+  enumerate all essentially different executions possible for a+  cryptographic protocol.  We call them the shapes of the protocol.+  Naturally occurring protocols have only finitely many, indeed very+  few shapes.  Authentication and secrecy properties are easy to+  determine from them, as are attacks and anomalies.+  .+  For each input problem, the CPSA program is given some initial+  behavior, and it discovers what shapes are compatible with it.+  Normally, the initial behavior is from the point of view of one+  participant.  The analysis reveals what the other participants must+  have done, given the participant's view.+  .+  We are working towards a version of CPSA with the property that+  whenever it successfully terminates, every possible execution is+  described by its output.  However, the current implementation+  occasionally fails to find some executions.+  .+  The package contains a set of programs used to perform and display+  the analysis.  Program documentation is in the doc directory in the+  source distribution, and installed in the package's data directory.+  You can locate the package's data directory by searching for the+  file cpsauser.html.  New users should study the documentation and+  the sample inputs in the data directory.  The source distribution+  includes a test suite with an expanded set of input files and+  program design documentation.+  .+  The theory and algorithm used by CPSA was developed with the help of+  Joshua D. Guttman, John D. Ramsdell, Jon C. Herzog, Shaddin+  F. Doghmi, F. Javier Thayer, and Paul D. Rowe.  John D. Ramsdell+  implemented the algorithm in Haskell. Category:		Cryptography Build-Type:		Simple Data-Files:@@ -26,24 +49,23 @@ --   ffgg.scm ns.scm or.scm woolam.scm yahalom.scm -- Data-Dir:	    	doc Extra-Source-Files:-  Makefile ChangeLog README NEWS ghci cpsatst doc/README-  doc/Makefile doc/macros.tex doc/cpsaprimer.tex doc/bcasyntax.tex-  doc/cpsaspec.tex doc/cpsadesign.tex doc/cpsaoverview.tex-  doc/cpsadiagrams.mp doc/strands.mp doc/cmstrands.mp doc/carriers.mp-  doc/termtree.mp doc/cpsa.bib doc/SDAG.lhs src/index.html-  src/cpsacgi src/cpsacgi.py src/cpsa2svg src/cpsa.el-  src/httpd_allow_execmem.te src/cpsaops.scm src/preskel-  src/sexpr.pl tst/README tst/Makefile tst/Make.hs tst/checktst-  tst/cpsagraphall tst/cpsashapesall tst/dass.lisp-  tst/completeness-test.scm tst/completeness-test.tst-  tst/missing-contraction.scm tst/missing-contraction.tst-  tst/dass-mod.lisp tst/dass_simple.scm tst/dass_simple.tst-  tst/denning-sacco.scm tst/denning-sacco.tst tst/dh.sch tst/dh.tst-  tst/ds-short.lisp tst/dy.lsp tst/dy.tst tst/epmo_acctnum.lsp-  tst/epmo_acctnum.tst tst/epmo.scm tst/encsig.scm tst/encsig.tst-  tst/epmo.tst tst/ffgg.scm tst/ffgg.tst tst/isoreject.scm-  tst/isoreject.tst tst/kelly1.scm tst/kelly1.tst tst/kelly64.lisp-  tst/kerb5.lisp tst/kerberos.scm tst/kerberos.tst+  Makefile ChangeLog README NEWS ghci cpsatst doc/README doc/Makefile+  doc/macros.tex doc/cpsaprimer.tex doc/bcasyntax.tex doc/cpsaspec.tex+  doc/cpsadesign.tex doc/cpsaoverview.tex doc/cpsadiagrams.mp+  doc/strands.mp doc/cmstrands.mp doc/carriers.mp doc/termtree.mp+  doc/cpsa.bib doc/SDAG.lhs src/index.html src/cpsacgi src/cpsacgi.py+  src/cpsa2svg src/cpsa.el src/httpd_allow_execmem.te src/cpsaops.scm+  src/preskel src/cpsa.pl src/pp.pl src/sexpr.pl+  tst/README tst/Makefile tst/Make.hs tst/checktst tst/cpsagraphall+  tst/cpsashapesall tst/dass.lisp tst/completeness-test.scm+  tst/completeness-test.tst tst/missing-contraction.scm+  tst/missing-contraction.tst tst/dass-mod.lisp tst/dass_simple.scm+  tst/dass_simple.tst tst/denning-sacco.scm tst/denning-sacco.tst+  tst/dh.sch tst/dh.tst tst/ds-short.lisp tst/dy.lsp tst/dy.tst+  tst/epmo_acctnum.lsp tst/epmo_acctnum.tst tst/epmo.scm+  tst/encsig.scm tst/encsig.tst tst/epmo.tst tst/ffgg.scm tst/ffgg.tst+  tst/isoreject.scm tst/isoreject.tst tst/kelly1.scm tst/kelly1.tst+  tst/kelly64.lisp tst/kerb5.lisp tst/kerberos.scm tst/kerberos.tst   tst/neuman-stubblebine-alt.lisp tst/neuman-stubblebine-reauth.lisp   tst/neuman-stubblebine-reauth.lsp tst/neuman-stubblebine-reauth.tst   tst/neuman-stubblebine.scm tst/neuman-stubblebine.tst tst/nsl3.scm
doc/cpsaoverview.pdf view

binary file changed (75334 → 75334 bytes)

doc/cpsaprimer.pdf view

binary file changed (177855 → 177855 bytes)

doc/cpsauser.html view
@@ -23,7 +23,7 @@ are easy to determine from them, as are attacks and anomalies.</p>  <p>For each input problem, the CPSA program is given some initial behavior, and-it descovers what shapes are compatible with it. Normally, the initial behavior+it discovers what shapes are compatible with it. Normally, the initial behavior is from the point of view of one participant. The analysis reveals what the other participants must have done, given the participant's view. The search is based on a high-level algorithm shown to be complete, i.e. every shape can in@@ -50,7 +50,7 @@ href="#cpsapp"><tt>cpsapp</tt></a> program pretty prints its input using the CPSA specific algorithm.</p> -<p>The input syntax is essentially the same as the output systax. A Lisp aware+<p>The input syntax is essentially the same as the output syntax. A Lisp aware editor will pretty print input, and the output is pretty printed. We use Emacs' Scheme mode to prepare input. This document describes the syntax, but provides little assistance for its interpretation. See the CPSA Tutorial document for@@ -258,7 +258,7 @@ option <tt>+RTS -M512m -RTS</tt> limits memory usage to 512m.</p>  <p>For long running problems, SMP parallelism is available. For example, on a-quad-core machine, we would prrobably use <tt>+RTS -N4 -RTS</tt>.</p>+quad-core machine, we would probably use <tt>+RTS -N4 -RTS</tt>.</p>  <p>When run with isomorphism checks disabled (<tt>--noisochk</tt>), CPSA searches for realized skeletons, not shapes. It attempts to speed up analysis
doc/macros.tex view
@@ -1,5 +1,5 @@ \newcommand{\cpsa}{\textsc{cpsa}}-\newcommand{\version}{2.0.1}+\newcommand{\version}{2.0.3} \newcommand{\cpsacopying}{\begingroup   \renewcommand{\thefootnote}{}\footnotetext{{\copyright} 2009 The     MITRE Corporation.  Permission to copy without fee all or part of
src/CPSA/Lib/Cohort.hs view
@@ -191,6 +191,9 @@                 else                     Just $ testNode k u ts der (graphNode n) t +useEncryptionFirstOrder :: Bool+useEncryptionFirstOrder = True+ -- Look for a critical term that makes this node a test node. testNode :: Algebra t p g s e c => Preskel t p g s e c ->             [t] -> Set t -> (t -> Bool) -> Node -> t ->@@ -207,8 +210,13 @@                     loop cts                 else                     solveNode k ct ek n t escape-      cts = map g (filter h (encryptions t)) ++-            map f (filter (flip carriedBy t) u)+      cts = +          if useEncryptionFirstOrder then+              map g (filter h (encryptions t)) +++              map f (filter (flip carriedBy t) u)+          else+              map f (filter (flip carriedBy t) u) +++              map g (filter h (encryptions t))       f ct = (ct, Nothing)       g (ct, ek) = (ct, Just ek)       h (_, ek) = not (derivable ek)
src/CPSA/Lib/Strand.hs view
@@ -1431,11 +1431,7 @@ skelNons k =     filter (flip notElem ru) (knon k)     where-      ru = [u | i <- insts k, u <- roleNons i]--roleNons :: Algebra t p g s e c => Instance t p g s e c -> [t]-roleNons i =-    map (instantiate (env i) . snd) (rnon (role i))+      ru = [u | i <- insts k, u <- inheritRnon i]  -- Uniquely-originating terms @@ -1452,11 +1448,7 @@ skelUniques k =     filter (flip notElem ru) (kunique k)     where-      ru = [u | i <- insts k, u <- roleUniques i]--roleUniques :: Algebra t p g s e c => Instance t p g s e c -> [t]-roleUniques i =-    map (instantiate (env i)) (runique (role i))+      ru = [u | i <- insts k, u <- inheritRunique i]  -- Variable separation 
src/CPSA/Lib/Utilities.hs view
@@ -9,6 +9,7 @@ module CPSA.Lib.Utilities where  import qualified Data.Set as S+import Data.List (foldl')  adjoin :: Eq a => a -> [a] -> [a] adjoin x xs@@ -52,8 +53,8 @@       numbering = dfs adj (S.toList start)       -- Remove nodes that have non-zero indegree       start = S.difference (S.fromList nodes) (S.map fst edges)-      edges = foldl f S.empty nodes-      f edges src = foldl (g src) edges (adj src)+      edges = foldl' f S.empty nodes+      f edges src = foldl' (g src) edges (adj src)       g src edges dst = S.insert (dst, src) edges  -- Compute a depth first search numbering of nodes using postorder.@@ -63,14 +64,14 @@ dfs adj nodes =     alist     where-      (_, alist, _) = foldl po (0, [], S.empty) nodes+      (_, alist, _) = foldl' po (0, [], S.empty) nodes       po a@(num, alist, seen) node          | S.member node seen = a          | otherwise =              (num' + 1, (node, num') : alist', seen'')              where  -- Search is postorder because nodes at the end of                (num', alist', seen'') = -- edges are explored before-                   foldl po (num, alist, seen') nodes' -- the node+                   foldl' po (num, alist, seen') nodes' -- the node                seen' = S.insert node seen -- Insert node as soon as                nodes' = adj node          -- it's seen 
+ src/cpsa.pl view
@@ -0,0 +1,227 @@+% -*- mode: prolog -*-++%% CPSA tools in Prolog++%% This module contains a Prolog implementation of the CPSA specific+%% S-expression pretty printer algorithm used in the Haskell program.+%% It also contains a translator between an S-expression and an+%% internal representation that eases transformations on CPSA data+%% structures.++%% Known to work in SWI-Prolog, but not with GNU Prolog.++%% Copyright (c) 2009 The MITRE Corporation+%%+%% This program is free software: you can redistribute it and/or+%% modify it under the terms of the BSD License as published by the+%% University of California.++:- module(cpsa, [cpsa_sexprs_pp/2, cpsa/2, sexprs_to_cpsas/2,+                 cpsas_to_sexprs/2]).++:- use_module(pp).+:- use_module(sexpr).++%% cpsa_sexprs_pp(+Out, +Sexprs)+%% Pretty print a list of S-expressions to stream Out.+cpsa_sexprs_pp(_, []).+cpsa_sexprs_pp(Out, [Sexpr|Sexprs]) :-+	cpsa_sexpr_pp(Out, Sexpr),+	nl(Out),+	cpsa_sexprs_pp(Out, Sexprs).++cpsa_sexpr_pp(Out, Sexpr) :-+	cpsa_sexpr_to_pretty(Sexpr, Pretty),+	pp:pr(Out, 72, Pretty),+	nl(Out).++%% Create a pretty printing tree for each top-level CPSA form.+cpsa_sexpr_to_pretty([comment|X], Pretty) :-+	sexpr:sexpr_to_pretty([comment|X], Pretty).+cpsa_sexpr_to_pretty([defskeleton|X], Pretty) :-+	sexpr_to_cpsa_pretty([defskeleton|X], Pretty).+cpsa_sexpr_to_pretty([defprotocol, Name, Alg|Roles], Pretty) :-+	pp:atm(defprotocol, X),+	pp:atm(Name, Y),+	pp:atm(Alg, Z),+	pp:atm('(', P),+	pp:atm(' ', S),+	sexpr_to_role_pretty(Roles, Pretties),+	pp:grp(2, [P, X, S, Y, S, Z, S|Pretties], Pretty).++%% CPSA role specific pretty printing support.+sexpr_to_role_pretty([[defrole|X]|Roles], [Space, Pretty|Pretties]) :-+	!,+	pp:brk(1, Space),+	sexpr_to_cpsa_pretty([defrole|X], Pretty),+	sexpr_to_role_pretty(Roles, Pretties).+sexpr_to_role_pretty(Sexprs, Pretties) :-+	sexprs_to_pretty(Sexprs, Pretties).++%% Creates a group in which breaks are allowed only before lists.+sexpr_to_cpsa_pretty(Thing, Pretty) :-+	atomic(Thing),+	!,+	sexpr:atom_to_pretty(Thing, Pretty).+sexpr_to_cpsa_pretty([Sexpr|Sexprs], Pretty) :-+	pp:atm('(', First),+	sexpr:sexpr_to_pretty(Sexpr, Second),+	sexprs_to_cpsa_pretty(Sexprs, Rest),+	pp:grp(2, [First, Second|Rest], Pretty).++sexprs_to_cpsa_pretty([], [Pretty]) :-+	pp:atm(')', Pretty).+sexprs_to_cpsa_pretty([Sexpr|Sexprs], [Space, Pretty|Pretties]) :-+	atomic(Sexpr),+	!,+	pp:atm(' ', Space),+	sexpr:sexpr_to_pretty(Sexpr, Pretty),+	sexprs_to_cpsa_pretty(Sexprs, Pretties).+sexprs_to_cpsa_pretty([Sexpr|Sexprs], [Space, Pretty|Pretties]) :-+	pp:brk(1, Space),+	sexpr:sexpr_to_pretty(Sexpr, Pretty),+	sexprs_to_cpsa_pretty(Sexprs, Pretties).++%% Translate between S-expressions and an internal form.++%% Currently, you have to read the code or look at output to+%% understand the internal form.++cpsa(File, Cpsas) :-+	sexpr:read_sexpr_list(File, Sexprs),+	sexprs_to_cpsas(Sexprs, Cpsas).++sexprs_to_cpsas([], []).+sexprs_to_cpsas([Sexpr|Sexprs], [Cpsa|Cpsas]) :-+	sexpr_to_cpsa(Sexpr, Cpsa),+	sexprs_to_cpsas(Sexprs, Cpsas).++sexpr_to_cpsa([comment|X], c(X)).+sexpr_to_cpsa([defprotocol, Name, Alg|Rest],+	p(Name, Alg, Roles)) :-+	atom(Name), atom(Alg),+	sexpr_to_roles(Rest, Roles).+sexpr_to_cpsa([defskeleton, Prot, [vars|Vars]|Rest],+	k(Prot, Decls, Strands, Precedes, Nons, Uniqs)) :-+	atom(Prot),+	decls(Vars, Decls),+	sexpr_to_strands(Rest, Strands, Alist),+	lookup(precedes, Alist, Values),+	edges(Values, Precedes),+	lookup('non-orig', Alist, Nons),+	lookup('uniq-orig', Alist, Uniqs).++sexpr_to_roles([[defrole|Sexpr]|Rest], [Role|Roles]) :-+	!,+	sexpr_to_role(Sexpr, Role),+	sexpr_to_roles(Rest, Roles).+sexpr_to_roles(_, []).++sexpr_to_role([Name, [vars|Vars], [trace|Trace]|Alist],+	r(Name, Decls, Trace, Nons, Uniqs)) :-+	decls(Vars, Decls),+	lookup('non-orig', Alist, Nons),+	lookup('uniq-orig', Alist, Uniqs).++sexpr_to_strands([[defstrand|Sexpr]|Rest], [Strand|Strands], Alist) :-+	!,+	sexpr_to_strand([defstrand|Sexpr], Strand),+	sexpr_to_strands(Rest, Strands, Alist).+sexpr_to_strands([[deflistener|Sexpr]|Rest], [Strand|Strands], Alist) :-+	!,+	sexpr_to_strand([deflistener|Sexpr], Strand),+	sexpr_to_strands(Rest, Strands, Alist).+sexpr_to_strands(Alist, [], Alist).++sexpr_to_strand([defstrand, Role, Height|Sexprs], s(Role, Height, Map)) :-+	atom(Role),+	integer(Height),+	maplets(Sexprs, Map).+sexpr_to_strand([deflistener, Term], l(Term)).++decls([], []).+decls([Sexpr|Sexprs], [Decl|Decls]) :-+	decl(Sexpr, Decl),+	decls(Sexprs, Decls).++decl(Sexprs, d(Type, Vars)) :-+	decl_vars(Sexprs, Type, Vars).++decl_vars([Type], Type, []) :-+	!,+	atom(Type).+decl_vars([Var|Decl], Type, [Var|Vars]) :-+	atom(Var),+	decl_vars(Decl, Type, Vars).++maplets([], []).+maplets([[Key, Value]|Sexprs], [[Key|Value]|Map]) :-+	maplets(Sexprs, Map).++lookup(_, [], []).+lookup(Key, [[Key|Value]|Alist], Values) :-+	!,+	append(Value, Rest, Values),+	lookup(Key, Alist, Rest).+lookup(Key, [[_|_]|Alist], Values) :-+	lookup(Key, Alist, Values).++edges([], []).+edges([Sexpr|Sexprs], [Edge|Edges]) :-+	edge(Sexpr, Edge),+	edges(Sexprs, Edges).++edge([S0, S1], [N0|N1]) :-+	node(S0, N0),+	node(S1, N1).++node([S, P], [S|P]) :-+	integer(S),+	integer(P).++%% Translate the internal form to an S-expression.++cpsas_to_sexprs([], []).+cpsas_to_sexprs([Cpsa|Cpsas], [Sexpr|Sexprs]) :-+	cpsa_to_sexpr(Cpsa, Sexpr),+	cpsas_to_sexprs(Cpsas, Sexprs).++cpsa_to_sexpr(c(X), [comment|X]).+cpsa_to_sexpr(p(Name, Alg, Roles), [defprotocol, Name, Alg|Rest]) :-+	roles_to_sexprs(Roles, Rest).+cpsa_to_sexpr(k(Prot, Decls, Strands, Precedes, Nons, Uniqs),+	[defskeleton, Prot, [vars|Vars]|Rest]) :-+	decls(Vars, Decls),+	preds(Precedes, Nons, Uniqs, Alist),+	strands_to_sexprs(Strands, Alist, Rest).++preds([], Nons, Uniqs, Alist) :-+	!,+	origs(Nons, Uniqs, Alist).+preds(Precedes, Nons, Uniqs, [[precedes|Sexprs]|Alist]) :-+	edges(Sexprs, Precedes),+	origs(Nons, Uniqs, Alist).++strands_to_sexprs([], Alist, Alist).+strands_to_sexprs([Strand|Strands], Alist, [Sexpr|Sexprs]) :-+	sexpr_to_strand(Sexpr, Strand),+	strands_to_sexprs(Strands, Alist, Sexprs).++roles_to_sexprs([], []).+roles_to_sexprs([Role|Roles], [Sexpr|Sexprs]) :-+	role_to_sexpr(Role, Sexpr),+	roles_to_sexprs(Roles, Sexprs).++role_to_sexpr(r(Name, Decls, Trace, Nons, Uniqs),+	[defrole, Name, [vars|Vars], [trace|Trace]|Alist]) :-+	decls(Vars, Decls),+	origs(Nons, Uniqs, Alist).++origs([], Uniqs, Alist) :-+	!,+	uniq_origs(Uniqs, Alist).+origs(Nons, Uniqs, [['non-orig'|Nons]|Alist]) :-+	uniq_origs(Uniqs, Alist).++uniq_origs([], []) :- !.+uniq_origs(Uniqs, [['uniq-orig'|Uniqs]]).
+ src/pp.pl view
@@ -0,0 +1,176 @@+% -*- mode: prolog -*-++%% A simple pretty printer++%% Construct a pretty printer tree using the tree constructors atm,+%% brk, blo, and grb, and then print it with pr.++%% The alogithm is by Lawrence C. Paulson, who simplified an algorithm+%% by Derek C. Oppen.++%% Derek C. Oppen, Prettyprinting, ACM Transactions on Programming+%% Languages and Systems, Vol 2, No. 4, October 1980, Pages 465-483.++%% Copyright (c) 2009 The MITRE Corporation+%%+%% This program is free software: you can redistribute it and/or+%% modify it under the terms of the BSD License as published by the+%% University of California.++%% A pretty printer based on ML programs with the following copyright++%% (**** ML Programs from Chapter 8 of++%%   ML for the Working Programmer, 2nd edition+%%   by Lawrence C. Paulson, Computer Laboratory, University of Cambridge.+%%   (Cambridge University Press, 1996)++%% Copyright (C) 1996 by Cambridge University Press.+%% Permission to copy without fee is granted provided that this copyright+%% notice and the DISCLAIMER OF WARRANTY are included in any copy.++%% DISCLAIMER OF WARRANTY.  These programs are provided `as is' without+%% warranty of any kind.  We make no warranties, express or implied, that the+%% programs are free of error, or are consistent with any particular standard+%% of merchantability, or that they will meet your requirements for any+%% particular application.  They should not be relied upon for solving a+%% problem whose incorrect solution could result in injury to a person or loss+%% of property.  If you do use the programs or functions in such a manner, it+%% is at your own risk.  The author and publisher disclaim all liability for+%% direct, incidental or consequential damages resulting from your use of+%% these programs or functions.+%% ****)++% Known to work in SWI-Prolog, but not with GNU Prolog.++:- module(pp, [atm/2, brk/2, blo/3, grp/3, pr/2, pr/3]).++%% Pretty printer tree constructors++%% Atoms (Strings str in the original code)+%% atm(+Atom, -Pretty)+atm(Atom, atm(Codes)) :-+	atomic(Atom),+	!,+	atom_codes(Atom, Codes).+atm(Codes, atm(Codes)).++%% Break points, where Len is the number of spaces to print when the+%% break is not turned into a newline break.+%% brk(+Len, -Pretty)+brk(Len, brk(Len)) :-+	integer(Len).++%% Indentation blocks (any number of breaks may be turned into a+%% newline break).+%% blk(+Indent, +Pretties, -Pretty)+blo(Indent, Pretties, blo(Pretties, Indent, Len)) :-+	len(Pretties, Len).++%% Indentation groups (all or none of the breaks are turned into+%% newline breaks)+%% grp(+Indent, +Pretties, -Pretty)+grp(Indent, Pretties, grp(Pretties, Indent, Len)) :-+	len(Pretties, Len).++% Compute the unbroken length of a list of pretty printing trees.+len(Pretties, Len) :-+	len(Pretties, 0, Len).++len([], Len, Len).+len([Pretty|Pretties], Start, Out) :-+	size(Pretty, Len),+	End is Start + Len,+	len(Pretties, End, Out).++size(atm(Codes), Len) :-+	length(Codes, Len).+size(brk(Len), Len).+size(blo(_, _, Len), Len).+size(grp(_, _, Len), Len).++%% After generating a pretty printing tree, print it++%% pr(+Margin, +Pretty)+pr(Margin, Pretty) :-+	current_output(Stream),+	pr(Stream, Margin, Pretty).++%% pr(+Stream, +Margin, +Pretty)+pr(Stream, Margin, Pretty) :-+	printing(Stream, Margin, [Pretty], Margin, 0, false, Margin, _).++%% Pretty print lists of trees+printing(_, _, [], _, _, _, Space, Space).+printing(Stream, Margin, [Pretty|Pretties],+	Blockspace, After, Force, Start, End) :-+	pretty_print(Stream, Margin, Pretty, Pretties,+	Blockspace, After, Force, Start, Mid),+	printing(Stream, Margin, Pretties,+	Blockspace, After, Force, Mid, End).++%% Print a string+pretty_print(Stream, _, atm(Codes), _, _,+	_, _, Start, End) :-+	put_codes(Stream, Codes),+	length(Codes, Len),+	End is Start - Len.+%% Print a break point without a newline break+pretty_print(Stream, _, brk(Len), Pretties, _,+	After, false, Start, End) :-+	break_dist(Pretties, After, Dist),+	Len + Dist =< Start,+	!,+	put_blanks(Stream, Len),+	End is Start - Len.+%% Print a break point with a newline break+pretty_print(Stream, Margin, brk(_), _, Blockspace,+	_, _, _, Blockspace) :-+	nl(Stream),+	End is Margin - Blockspace,+	put_blanks(Stream, End).+%% Print a block+pretty_print(Stream, Margin, blo(Body, Indent, _), Pretties, _,+	After, _, Start, End) :-+	New is Start - Indent,+	break_dist(Pretties, After, Dist),+	printing(Stream, Margin, Body, New, Dist, false, Start, End).+%% Print a group+pretty_print(Stream, Margin, grp(Body, Indent, Len), Pretties, _,+	After, _, Start, End) :-+	New is Start - Indent,+	break_dist(Pretties, After, Dist),+	(Len + Dist > Start -> Force = true; Force = false),+	printing(Stream, Margin, Body, New, Dist, Force, Start, End).++%% Find the distance to the next break point+break_dist([], After, After).+break_dist([atm(Codes)|Pretties], After, Dist) :-+	break_dist(Pretties, After, Mid),+	length(Codes, Len),+	Dist is Mid + Len.+break_dist([brk(_)|_], _, 0).+break_dist([blo(_, _, Len)|Pretties], After, Dist) :-+	break_dist(Pretties, After, Mid),+	Dist is Mid + Len.+break_dist([grp(_, _, Len)|Pretties], After, Dist) :-+	break_dist(Pretties, After, Mid),+	Dist is Mid + Len.++%% Printing primitives+put_blanks(Stream, Len) :-+	0 < Len,+	!,+	put_blank(Stream),+	Next is Len - 1,+	put_blanks(Stream, Next).+put_blanks(_, _).++put_blank(Stream) :-+	atom_codes(' ', Codes),+	put_codes(Stream, Codes).++put_codes(_, []).+put_codes(Stream, [Code|Codes]) :-+	put_code(Stream, Code),+	put_codes(Stream, Codes).
src/sexpr.pl view
@@ -1,13 +1,27 @@ % -*- mode: prolog -*- -% Converts lists of character codes to Prolog style S-Expressions.+%% Converts lists of character codes to Prolog style S-Expressions and+%% generates pretty printer trees for S-expressions for use with the+%% exports of the pretty printer module pp. -% Known to work in SWI-Prolog, but not with GNU Prolog.+%% Known to work in SWI-Prolog, but not with GNU Prolog.  The program+%% makes use of the non-standard atomic data type string to represent+%% strings in S-expressions.  Atoms and integers in S-expressions are+%% mapped to Prolog standard atoms and numbers. -:- module(sexpr,-	  [codes_sexpr/2, codes_sexpr_list/2, sexpr_term/2,-	   read_sexpr_list/2, read_sexpr_term_list/2]).+%% Copyright (c) 2009 The MITRE Corporation+%%+%% This program is free software: you can redistribute it and/or+%% modify it under the terms of the BSD License as published by the+%% University of California. +:- module(sexpr, [codes_sexpr/2, codes_sexpr_list/2, sexpr_term/2,+	  read_sexpr_list/2, read_sexpr_term_list/2, atom_to_pretty/2,+	  sexpr_to_pretty/2, sexprs_to_pretty/2,+	  sexpr_to_group_pretty/2]).++:- use_module(pp).+ % codes_sexpr(+Codes, -Sexpr)  % Convert a list of character codes to a Prolog style S-Expression.@@ -280,6 +294,7 @@  % Intrepret the character codes from a file as a list of S-Expressions. +%% read_sexpr_list(+Name, -Sexprs) read_sexpr_list(Name, Sexprs) :- 	read_file(Name, Codes), 	codes_sexpr_list(Codes, Sexprs).@@ -290,6 +305,57 @@ % in which lists that start with an atom have been converted to a % function application. +%% read_sexpr_list(+Name, -Terms) read_sexpr_term_list(Name, Terms) :- 	read_sexpr_list(Name, Sexprs), 	sexpr_term_list(Sexprs, Terms).++%% Generates pretty printer trees for S-expressions.++%% atom_to_pretty(+Sexpr, -Pretty)+atom_to_pretty([], Pretty) :-+	!,+	pp:atm('()', Pretty).+atom_to_pretty(Thing, Pretty) :-+	string(Thing),+	!,+	atom_codes('"', Quote),+	string_to_list(Thing, Codes),+	append(Quote, Codes, X),+	append(X, Quote, String),+	pp:atm(String, Pretty).+atom_to_pretty(Thing, Pretty) :-+	atomic(Thing),+	pp:atm(Thing, Pretty).++%% Creates blocks for all lists+%% sexpr_to_pretty(+Sexpr, -Pretty)+sexpr_to_pretty(Thing, Pretty) :-+	atomic(Thing),+	!,+	atom_to_pretty(Thing, Pretty).+sexpr_to_pretty([Sexpr|Sexprs], Pretty) :-+	pp:atm('(', First),+	sexpr_to_pretty(Sexpr, Second),+	sexprs_to_pretty(Sexprs, Rest),+	pp:blo(2, [First, Second|Rest], Pretty).++%% sexprs_to_pretty(+Sexprs, -Pretties)+sexprs_to_pretty([], [Pretty]) :-+	pp:atm(')', Pretty).+sexprs_to_pretty([Sexpr|Sexprs], [Space, Pretty|Pretties]) :-+	pp:brk(1, Space),+	sexpr_to_pretty(Sexpr, Pretty),+	sexprs_to_pretty(Sexprs, Pretties).++%% Creates a group for the top-level list, and then blocks for all+%% interior lists.+%% sexpr_to_group_pretty(+Sexpr, -Pretty)+sexpr_to_group_pretty([Sexpr|Sexprs], Pretty) :-+	!,+	pp:atm('(', First),+	sexpr_to_pretty(Sexpr, Second),+	sexprs_to_pretty(Sexprs, Rest),+	pp:grp(2, [First, Second|Rest], Pretty).+sexpr_to_group_pretty(Sexpr, Pretty) :-+	sexpr_to_pretty(Sexpr, Pretty).
tst/completeness-test.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol completeness-test basic
tst/dass_simple.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol dass basic
tst/denning-sacco.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol denning-sacco basic
tst/dh.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol dhke diffie-hellman
tst/dy.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol dy basic
tst/encsig.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol mult-keys-enc-sig basic
tst/epmo.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol epmo basic
tst/epmo_acctnum.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol epmo_acctnum basic
tst/ffgg.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol ffgg basic
tst/isoreject.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol isoreject basic
tst/kelly1.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol kelly1 basic
tst/kerberos.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol kerberos basic
tst/missing-contraction.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol missing-contraction basic
tst/neuman-stubblebine-reauth.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol neuman-stubblebine basic
tst/neuman-stubblebine.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol neuman-stubblebine basic
tst/ns.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol ns basic
tst/nsl3.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol nsl3 basic
tst/nsl4cm1.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol nsl4cm basic
tst/nslsk.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol nslsk basic
tst/or.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol or basic
tst/pca.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol aic basic
tst/sigenc.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol mult-keys-sig-enc basic
tst/sorted_epmo_acctnum.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol epmo_acctnum basic
tst/weird.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol wierd basic
tst/wmf.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol wide-mouth-frog basic
tst/woolam.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol woolam basic
tst/yahalom.tst view
@@ -1,4 +1,4 @@-(comment "CPSA 2.0.2")+(comment "CPSA 2.0.3") (comment "All input read")  (defprotocol yahalom basic