Commits

Michael Richter committed 57f5de5

Oops. Forgot to actually add the files here.

  • Participants
  • Parent commits 16feec9

Comments (0)

Files changed (2)

File prolog/destructive.pl

+%-----------------------------------------------------------------------------%
+% vim: ft=prolog ts=4 sw=4 et wm=0 tw=0
+%-----------------------------------------------------------------------------%
+:-module(destruction, [ ':='/2,   op(700, xfx, :=),
+                        ':=:'/2,  op(700, xfx, :=:),
+                        iss/2,    op(700, xfx, iss),
+                        '++'/1,   op(500, xf,  ++),
+                        '--'/1,   op(500, xf,  --),
+                        '+:+'/1,  op(500, xf,  +:+),
+                        '-:-'/1,  op(500, xf,  -:-),
+                        '++'/1,   op(500, fx,  ++),
+                        '--'/1,   op(500, fx,  --),
+                        '+:+'/1,  op(500, fx,  +:+),
+                        '-:-'/1,  op(500, fx,  -:-),
+                        defvar/1, op(400, fx,  defvar)  ]).
+
+
+/** <module> Destructive variables (d-variables)
+  *  
+ * Aren't we all bored of NN is N+1? Why go through all this hassle?
+ * Good news everyone: this module allows you to release your inner god of chaos
+ * and use destructive assignment - in PROLOG!
+ *
+ * Of course, everything comes with a price; if you thought that
+ * =/2 vs ==/2 vs =':='/2 vs is/2 is confusing then you might want to run...
+ *
+ *  @author      Thanos Tintinidis <thanosqr@gmail.com>
+ *  @version     1.0
+ *  @see         http://en.wikipedia.org/wiki/Alignment_%28Dungeons_%26_Dragons%29#Chaotic_Evil
+ *  @deprecated
+ *  @license     This program is free software. It comes without any warranty,
+ *               to the extent permitted by applicable law. You can
+ *               redistribute it and/or modify it under the terms of the Do
+ *               What The Fuck You Want To Public License, Version 2, as
+ *               published by Sam Hocevar.  See the file COPYING in the project
+ *               root directory or consult http://sam.zoy.org/wtfpl/COPYING for
+ *               more details.
+ *  @tbd         Destructive assignments can never stop; therefore, this module
+ *               is eternally in a state of flux
+ */
+  
+
+%% defvar(Var:term) is det.
+%
+%  Since we are abandoning our high-level discipline, why not start declaring
+%  our variables? defvar/1 allows you to declare one empty d-variable (but most
+%  of the times it is pointless). Nevertheless, it demonstrates the basic
+%  structure of our variables: v(_value) (where v stands for eVil and Variable)
+%
+%  ==
+%  ?- defvar X.
+%  X = v(_G666).
+%  ==
+defvar v(_).
+
+%% :=(X:var, Y:var) is det.
+%
+%  ':='/2 will assign the value Y to X.  If Y contains instances of X, they
+%  will be replaced by its value to avoid cyclic terms Note that X can be a
+%  d-variable (empty or not) or a non-instantiated variable.
+%
+%  ==
+%  ?- X := 42.
+%  X = v(42).
+%  ?- X := 42, print(X), X := 17, print(X).
+%  4217
+%  X = v(17).
+%  ?- defvar(X), X := 42.
+%  X = v(42).
+%  ?-X:=1+1.
+%  X = v(1+1)
+%  ?- X:=1, X:=X+1.
+%  X = v(1+1)
+%  ?- X:=1, X := X+1+v(2)+v(3+v(32)).
+%  X = v(1+1+v(2)+v(3+v(32))).
+%  ==
+%
+%  @see ':=:'/2
+X := Y :- (    var(X) -> X = v(Y)
+          ;           ( replace_x(X,Y,YMX),
+                        setarg(1,X,YMX) ) ).
+
+%% :=:(X:var, Y:term) is det.
+%
+%  ':=:'/2 behaves similarly to ':='/2 but evaluates the expression Y before
+%  assigning it to X.
+%
+%  ==
+%  ?- X :=: 1.
+%  X = v(1).
+%  ?- X :=: 1+1.
+%  X = v(2).
+%  ?- X := 1+1.
+%  X = v(1+1).
+%  ?- X:=1, X :=: X+1.
+%  X = v(2).
+%  ?- X:=1, X :=: X+1+v(2)+v(3+v(32)).
+%  X = v(39).
+%  ==
+%
+%  @see ':='/2
+X :=: Y :- YY iss Y,
+           ( X = v(YY) -> true
+           ;              setarg(1,X,YY) ).
+
+
+%% iss(Y:var, X:term) is det.
+%
+%  iss/2 evaluates the expression X and assigns (non-destructively) the value
+%  to Y.
+%
+%  ==
+%  ?- Y iss 1+v(2)+v(3+v(32)).
+%  Y = 38.
+%  ?- v(Y) iss 1+v(2)+v(3+v(32)).
+%  false.
+%  ==
+
+Y iss X :- term_to_atom(X,A),
+           atom_chars(A,C),
+           phrase(var_term(PC),C),
+           atom_chars(PA,PC),
+           atom_to_term(PA,T,[]),
+           Y is T,!.
+
+%% ++(X:var) is semidet.
+%
+%  Adds one to the value of a d-variable.  If the d-variable is empty, an
+%  exception will be thrown.
+%
+%  Usage (covering ++/1, --/1, -:-/1, and +:+/1):
+%  ==
+%  ?- X := 1, X++ .
+%  X = v(1+1).
+%  ?- X := 1, ++X .
+%  X = v(1+1).
+%  ?- X := 1, +:+X.
+%  X = v(2).
+%  ?- X := 1, X++, X++ .
+%  X = v(1+1+1).
+%  ?- X := 1, X++, X++, +:+X.
+%  X = v(4).
+%  ==
+%
+%  @see +:+/1
+%  @see --/1
+%  @see -:-/1
+(X ++) :- vcheck(X), X := X + 1.
+
+%% +:+(X:var) is semidet.
+%
+%  Adds one to the value of a d-variable after evaluating it.  If the
+%  d-variable is empty, an exception will be thrown.
+%
+%  @see --/1
+%  @see +:+/1
+%  @see -:-/1
+(X +:+) :- vcheck(X), X :=: X + 1.
+
+%% --(X:var) is semidet.
+%
+%  Subtracts one from the value of a d-variable.  If the d-variable is empty,
+%  an exception will be thrown.
+%
+%  @see ++/1
+%  @see +:+/1
+%  @see -:-/1
+(X --) :- vcheck(X), X := X - 1.
+%
+%% -:-(X:var) is semidet.
+%
+%  Subtracts one from the value of a d-variable after evaluating it.  If the
+%  d-variable is empty, an exception will be thrown.
+%
+%  @see ++/1
+%  @see --/1
+%  @see +:+/1
+(X -:-) :- vcheck(X), X :=: X - 1.
+
+% Auxilliary predicates.  You are not meant to understand these.  They are
+% evil.  Just trust us on this.
+
+vcheck(v(X)):- ( var(X) -> throw('Arguments are not sufficiently instantiated')
+               ;           true ).
+
+var_term([]) -->     [].
+var_term(PC) -->     [v,'('], { ! },
+                     var_term(PC1),
+                     [')'], { ! },
+                     var_term(PC2),
+                     { append(PC1, PC2, PC) }.
+var_term([X|PC]) --> [X],
+                     var_term(PC).
+
+replace_x(X,Y,YMX):- term_chars(Y, YC),
+                     term_chars(X, XC),
+                     XC = ['v'| Value],
+                     phrase(del_x(PC, {XC, Value}), YC),
+                     term_chars(YMX, PC), !.
+
+del_x([], _) --> [].
+del_x(PC, {XC, Value}) --> XC, { ! },
+                           del_x(PCT, {XC, Value}),
+                           { append(Value, PCT, PC) }.
+del_x([X|PC], XC) -->      [X],
+                           del_x(PC, XC).
+
+term_chars(T, C):- var(C),
+                   term_to_atom(T, A),
+                   atom_chars(A, C).
+
+term_chars(T, C):- var(T),
+                   atom_chars(A, C),
+                   atom_to_term(A, T, []).

File prolog/hellgates.pl

+%-----------------------------------------------------------------------------%
+% vim: ft=prolog ts=4 sw=4 et wm=0 tw=0
+%-----------------------------------------------------------------------------%
+:-module(hellgates, [ and/2,  op(1000, xfy, and),
+					  or/2,   op(1100, xfy, or),
+					  nand/2, op(1100, xfy, nand),
+					  andn/2, op(1100, xfy, andn),
+					  nor/2,  op(1100, xfy, nor),
+					  orn/2,  op(1100, xfy, orn),
+					  xor/2,  op(1100, xfy, xor),
+					  orx/2,  op(1100, xfy, orx),
+					  xnor/2, op(1100, xfy, xnor),
+					  norx/2, op(1100, xfy, norx),
+					  xorn/2, op(1100, xfy, xorn),
+					  ornx/2, op(1100, xfy, ornx) ]).
+
+/** <module> Gates of Hell
+ *
+ *  An expansion of the Evil Prolog, this module allows you to follow the
+ *  example of so many heroes such as Orpheus, Aeneas and Odysseus:  denounce
+ *  the garish light of day and use these Gates for a trip in the netherworld!
+ *
+ *  This module allows you to use more sophisticated binary operators than the
+ *  trivial ',' and ';' hence enriching your prolog program.  Combined with the
+ *  closed-world hypothesis and unification issues, this module will definitely
+ *  boost your reasoning powers unless you abandon all hope of understanding
+ *  your program
+ *
+ *  @author      Thanos Tintinidis <thanosqr@gmail.com>
+ *  @version     1.0
+ *  @see         http://en.wikipedia.org/wiki/Gates_of_hell
+ *  @deprecated
+ *  @license     This program is free software. It comes without any warranty,
+ *               to the extent permitted by applicable law. You can
+ *               redistribute it and/or modify it under the terms of the Do
+ *               What The Fuck You Want To Public License, Version 2, as
+ *               published by Sam Hocevar.  See the file COPYING in the project
+ *               root directory or consult http://sam.zoy.org/wtfpl/COPYING for
+ *               more details.
+ *  @tbd         Hell has no bottom; therefore, this module is damned eternally
+ *               in a state of flux
+ */
+
+% Reminiscent of pascal? Why use the mundane ',' and ';' when this
+% module provides the longer (and more descriptive) 'and' and 'or'?
+
+%% and(X:term, Y:term) is semidet.
+%
+%  Pascal and other similar languages are so much easier to read with their actual
+%  *words* instead of punctuation.
+X and Y :- X, Y.
+
+%% or(X:term, Y:term) is semidet.
+%
+%  Pascal and other similar languages are so much easier to read with their actual
+%  *words* instead of punctuation.
+X or Y :- X; Y.
+
+%% nand(X:term, Y:term) is semidet.
+%
+%  Wanna give your co-workers a stroke? Then use a Sheffer stroke, also known
+%  as NAND; it is, after all, the only operator required for a functionally
+%  complete set, right?
+%
+%  ==
+%  1=1 nand 1=1.  %% false
+%  1=1 nand 1=2.  %% true
+%  1=2 nand 1=1.  %% true
+%  1=2 nand 1=2.  %% true
+%  ==
+% 
+%  But what happens when something is not fully instantiated?
+% 
+%  ==
+%  T=1 nand T=2.  %% true
+%  T=1 nand T=1.  %% false
+%  ==
+X nand Y :- \+ (X, Y).
+
+%% andn(X:term, Y:term) is semidet.
+%
+%  Some tasks may require a different behaviour from nand/2 so we included some
+%  alternate ways of handling non instantiated variables:
+% 
+%  ==
+%  T=1 andn T=2. %% false
+%  ==
+X andn Y :- once( (\+ X) ; (\+ Y)).
+
+%% nor(X:term, Y:term) is semidet.
+%
+%  Left mostly undocumented to stem *some* of the tide of evil.
+X nor Y :- \+ (X ; Y).
+
+%% orn(X:term, Y:term) is semidet.
+%
+%  Left mostly undocumented to stem *some* of the tide of evil.
+X orn Y :- \+ X, \+ Y.  
+
+%% xor(X:term, Y:term) is semidet.
+%
+%  Left mostly undocumented to stem *some* of the tide of evil.
+X xor Y :- once((X ; Y)), \+ (X,Y).
+
+%% orx(X:term, Y:term) is semidet.
+%
+%  Left mostly undocumented to stem *some* of the tide of evil.
+X orx Y :- once((X ; Y)), once((\+ X ; \+ Y)).
+
+%% xnor(X:term, Y:term) is semidet.
+%
+%  Left mostly undocumented to stem *some* of the tide of evil.
+X xnor Y :- \+ (X xor Y).
+
+%% norx(X:term, Y:term) is semidet.
+%
+%  Left mostly undocumented to stem *some* of the tide of evil.
+X norx Y :- once((X, Y) ; \+(X ; Y)).
+
+%% xorn(X:term, Y:term) is semidet.
+%
+%  Left mostly undocumented to stem *some* of the tide of evil.
+X xorn Y :- \+ ( \+ X, \+ Y).
+	
+%% ornx(X:term, Y:term) is semidet.
+%
+%  Left mostly undocumented to stem *some* of the tide of evil.
+X ornx Y :- once(X ; Y).