using System;
using JJC.Psharp.Lang;
using JJC.Psharp.Predicates;
using System.Xml;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Reflection;
namespace DCAServer {
///
/// Summary description for Class1.
///
class PredicateDescriptor {
public string name;
public ArrayList key;
public PredicateDescriptor( string name, ArrayList key ) {
this.name = name;
this.key = key;
}
}
class DCAServer {
static ArrayList predicates;
public static PushbackReader GetStringReader( string s ) {
StringReader sr = new StringReader( s );
return new PushbackReader( (TextReader)sr );
}
static void ReadTable( XmlTextReader reader ) {
while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.Element:
if( reader.Name.Equals( "predicate" ) ) {
ReadPredicateData( reader, reader.GetAttribute( "name" ) );
} else
throw new Exception( );
break;
case XmlNodeType.EndElement:
break;
case XmlNodeType.Whitespace:
break;
default:
throw new Exception( );
}
}
}
static void ReadPredicateData( XmlTextReader reader, string name ) {
ArrayList key = new ArrayList( );
while( reader.Read( ) ) {
switch( reader.NodeType ) {
case XmlNodeType.Element:
if( reader.Name.Equals( "field" ) ) {
string isKey = reader.GetAttribute( "key" );
key.Add( isKey );
reader.Read( );
if( !( reader.Name.Equals( "field" ) ) ||
!( reader.NodeType == XmlNodeType.EndElement ) )
throw new Exception( );
}
else
throw new Exception( );
break;
case XmlNodeType.EndElement:
if( !reader.Name.Equals( "predicate" ) )
throw new Exception( );
else {
predicates.Add( new PredicateDescriptor( name, key ) );
return;
}
case XmlNodeType.Whitespace:
break;
default:
throw new Exception( );
}
}
}
static void ReadXMLFile( string file ) {
XmlTextReader reader = new XmlTextReader( file );
reader.WhitespaceHandling = System.Xml.WhitespaceHandling.Significant;
try {
while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.Element:
if( reader.Name.Equals( "dcatable" ) )
ReadTable( reader );
else
throw new Exception( );
break;
case XmlNodeType.EndElement:
break;
case XmlNodeType.Whitespace:
break;
default:
throw new Exception( );
}
}
} finally {
if( reader != null )
reader.Close();
}
}
[STAThread]
static void Main(string[] args) {
predicates = new ArrayList( );
// args[0] should be a file, we will load the
// schema for the data therefrom (maybe this should be XML).
if( args.Length != 1 ) {
Console.WriteLine( "Usage: DCAServer " );
return;
}
string file = args[ 0 ];
ReadXMLFile( file );
// now dump all this data into the prolog engine,
// so that it can assert relevant predicates.
PrologInterface sharp = new PrologInterface( );
sharp.addCallingAssembly( );
sharp.setPredicate( new JJC.Psharp.Predicates.DcaInit_0(
new ReturnCs( sharp ) ) );
sharp.call( );
SymbolTerm key = SymbolTerm.makeSymbol( "key", 0 );
SymbolTerm nonkey = SymbolTerm.makeSymbol( "nonkey", 0 );
for( int i = 0; i < predicates.Count; i++ ) {
PredicateDescriptor pd = (PredicateDescriptor)
(predicates[ i ] );
string s = pd.name;
ArrayList k = pd.key;
Term lt = SymbolTerm.makeSymbol( "[]", 0 );
for( int j = k.Count - 1; j >= 0; j-- ) {
if( ((string)k[ j ]).Equals( "true" ) )
lt = new ListTerm( key, lt );
else
lt = new ListTerm( nonkey, lt );
}
sharp.setPredicate( new DcaAssertPred_3(
SymbolTerm.makeSymbol( s ),
new IntegerTerm( k.Count ),
lt, new ReturnCs( sharp ) ) );
sharp.call( );
}
/*
args = new string[] { "Cafeteria" };
if( args.Length == 0 )
args = new string[] { "Main" };
Assembly a = System.Reflection.Assembly.Load( "Psharp" );
a.GetType( "JJC.Psharp.Lang.PrologMain" ).GetMethod( "Main" ).
Invoke( a.CreateInstance( "JJC.Psharp.Lang.PrologMain" ),
new object[] { args } );
*/
RunServer( );
}
public static void BroadCast( string tb ) {
Console.Out.WriteLine( "Broadcast: " + tb );
try { BroadCast( tb, 6001 ); } catch { }
try { BroadCast( tb, 6002 ); } catch { }
try { BroadCast( tb, 6003 ); } catch { }
try { BroadCast( tb, 6004 ); } catch { }
}
public static void ResetAllPorts( object lt ) {
try { ResetAgents( lt, 6001 ); } catch { }
try { ResetAgents( lt, 6002 ); } catch { }
try { ResetAgents( lt, 6003 ); } catch { }
try { ResetAgents( lt, 6004 ); } catch { }
}
public static void BroadCast( string tb, int port ) {
TcpClient client = null;
NetworkStream output = null;
BinaryWriter writer = null;
try {
client = new TcpClient( );
client.Connect( "localhost", port );
output = client.GetStream( );
writer = new BinaryWriter( output );
writer.Write( tb );
} finally {
try { writer.Close( ); } catch { }
try { output.Close( ); } catch{ }
try { client.Close( ); } catch { }
}
}
public static void ResetAgents( object lt, int port ) {
TcpClient client = null;
NetworkStream output = null;
BinaryWriter writer = null;
try {
client = new TcpClient( );
client.Connect( "localhost", port );
output = client.GetStream( );
writer = new BinaryWriter( output );
writer.Write( "broadcast_all." );
Term result = ((ListTerm)lt).dereference( );
Term elm;
for ( ; ; ) {
elm = ((ListTerm)result).car.dereference();
writer.Write( "broadcast_assert( " + elm.ToString( ) + ". )." );
result = ((ListTerm)result).cdr.dereference();
if( !( result is ListTerm ) )
break;
}
writer.Write( "end." );
} catch( Exception e ) {
} finally {
try {
writer.Close( );
output.Close( );
client.Close( );
} catch { }
}
}
public static void BroadcastAssertTerm( Term t ) {
BroadCast( "broadcast_assert( " + t + ". )." );
}
public static void BroadcastAssert( string tba ) {
BroadCast( "broadcast_assert( " + tba + " )." );
}
public static void BroadcastRetract( string tbr ) {
BroadCast( "broadcast_retract( " + tbr + " )." );
}
public static void BroadcastAllRetract( ) {
BroadCast( "all_retract." );
}
public static object databaseLock = new object( );
public static void DoAssert( string tba ) {
lock( databaseLock ) {
PrologInterface sharp = new PrologInterface( );
sharp.setPredicate( new DcaAssert_1(
SymbolTerm.makeSymbol( tba ), new ReturnCs( sharp ) ) );
sharp.call( );
}
}
public static void DoRetract( string tbr ) {
lock( databaseLock ) {
PrologInterface sharp = new PrologInterface( );
sharp.setPredicate( new DcaRetract_1(
SymbolTerm.makeSymbol( tbr ), new ReturnCs( sharp ) ) );
sharp.call( );
}
}
public static string Strip( string sin ) {
int i = sin.IndexOf( "(" );
int j = sin.LastIndexOf( ")" );
string sout = sin.Substring( i + 2, j - i - 3 ) + ".";
return sout;
}
public static object resolveConflictLock = new object( );
public static int ResolveConflict( object lt,
object r, object w ) {
lock( resolveConflictLock ) {
BinaryReader reader = (BinaryReader)(r);
BinaryWriter writer = (BinaryWriter)(w);
writer.Write( "conflicts." );
Term result = ((ListTerm)lt).dereference( );
Term elm;
for ( ; ; ) {
elm = ((ListTerm)result).car.dereference();
writer.Write( elm.ToString( ) + "." );
result = ((ListTerm)result).cdr.dereference();
if( !( result is ListTerm ) )
break;
}
writer.Write( "!conflicts." );
string s = reader.ReadString( );
return Int32.Parse( s );
}
}
private static void HandleConnect( BinaryReader reader,
BinaryWriter writer, NetworkStream socketStream,
Socket connection ) {
PrologInterface sharp = new PrologInterface( );
ArrayList agentClauses = new ArrayList( );
string next;
while( !( next = reader.ReadString( ) ).Equals( "!claims." ) ) {
Console.Out.WriteLine( "received: " + next );
agentClauses.Add( next );
sharp.setPredicate( new DcaAssertNoCopy_1(
SymbolTerm.makeSymbol( next ), new ReturnCs( sharp ) ) );
sharp.call( );
}
Console.Out.WriteLine( "now resolving..." );
sharp.setPredicate( new ResolveAll_2(
new CsObjectTerm( reader ),
new CsObjectTerm( writer ),
new ReturnCs( sharp ) ) );
sharp.call( );
writer.Write( "ok." );
Console.Out.WriteLine( "ok." );
try { reader.Close( ); } catch { }
try { writer.Close( ); } catch { }
try { socketStream.Close( ); } catch { }
try { connection.Close( ); } catch { }
Console.Out.WriteLine( "now resetting all..." );
sharp.setPredicate( new ResetAllAgents_0( new ReturnCs( sharp ) ) );
sharp.call( );
}
private static void RunServer( ) {
TcpListener listener = new TcpListener( 6000 );
Socket connection;
NetworkStream socketStream;
BinaryWriter writer;
BinaryReader reader;
string msg;
try {
//listener = new TcpListener( 6000 );
listener.Start( );
while( true ) {
connection = listener.AcceptSocket( );
socketStream = new NetworkStream( connection );
writer = new BinaryWriter( socketStream );
reader = new BinaryReader( socketStream );
try {
msg = reader.ReadString( );
if( msg.StartsWith( "assert" ) ) {
DoAssert( Strip( msg ) );
}
else if( msg.StartsWith( "retract" ) ) {
DoRetract( Strip( msg ) );
}
else if( msg.Equals( "connect." ) ) {
Console.Out.WriteLine( "connect." );
HandleConnect( reader, writer,
socketStream, connection );
}
else if( msg.Equals( "disconnect." ) ) {
continue;
}
} catch( Exception ) {
} finally {
try { reader.Close( ); } catch { }
try { writer.Close( ); } catch { }
try { socketStream.Close( ); } catch { }
try { connection.Close( ); } catch { }
//try { listener.Stop( ); } catch { }
System.Console.Out.WriteLine( "closed connection." );
}
}
} catch( Exception e ) {
Console.WriteLine( "Error in runServer:\n" + e );
} finally {
listener.Stop( );
}
}
}
}