Skip to content

Commit

Permalink
optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
gkevin-kappas committed Aug 15, 2024
1 parent 9bd0c24 commit b899b42
Show file tree
Hide file tree
Showing 17 changed files with 100 additions and 67 deletions.
2 changes: 1 addition & 1 deletion Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
}

var shell = facade.BuildShell();
shell.WriteTable(["Query Parse", "Query Compile", "Query Execute", "Num Solutions"], times.ToArray());
shell.WriteTable(["Query Parse", "Query Compile", "Query Execute", "Num Solutions"], [.. times]);


public sealed class ErgoBenchmarks
Expand Down
4 changes: 2 additions & 2 deletions Ergo/Interpreter/ErgoInterpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public virtual bool RunDirective(ref InterpreterScope scope, Directive d)
{
var sig = directive.Signature.Explain();
var directiveWatch = Probe.Enter(sig);
var ret = directive.Execute(this, ref scope, ((Complex)d.Body).Arguments.ToArray());
var ret = directive.Execute(this, ref scope, [.. ((Complex)d.Body).Arguments]);
Probe.Leave(directiveWatch, sig);
return ret;
}
Expand Down Expand Up @@ -162,7 +162,7 @@ void Execute(Directive Ast, InterpreterDirective BuiltIn, ref InterpreterScope s
{
var sig = BuiltIn.Signature.Explain();
var builtinWatch = Probe.Enter(sig);
BuiltIn.Execute(this, ref scope, ((Complex)Ast.Body).Arguments.ToArray());
BuiltIn.Execute(this, ref scope, [.. ((Complex)Ast.Body).Arguments]);
// NOTE: It's only after module/2 has been called that the module actually gets its name!
Probe.Leave(builtinWatch, sig);
}
Expand Down
5 changes: 1 addition & 4 deletions Ergo/Interpreter/InterpreterScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ public InterpreterScope(ErgoFacade facade, Module userModule)
Entry = userModule.Name;
Modules = ImmutableDictionary.Create<Atom, Module>()
.Add(userModule.Name, userModule);
SearchDirectories = ImmutableArray<string>.Empty
.Add(@".\ergo\")
.Add(@".\user\")
;
SearchDirectories = [@".\ergo\", @".\user\"];
IsRuntime = userModule.IsRuntime;
ExceptionHandler = default;
VisibleModules = GetVisibleModules(Entry, Modules).ToImmutableArray();
Expand Down
2 changes: 1 addition & 1 deletion Ergo/Lang/Ast/Predicates/Predicate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ public static bool FromCanonical(ITerm term, Atom defaultModule, out Predicate p
pred = new("(dynamic)", mod, head, body, true, false, default);
return true;
}
pred = new("(dynamic)", module, term, new NTuple(ImmutableArray<ITerm>.Empty.Add(WellKnown.Literals.True), term.Scope), true, false, default);
pred = new("(dynamic)", module, term, new NTuple([WellKnown.Literals.True], term.Scope), true, false, default);
return true;
}

Expand Down
5 changes: 2 additions & 3 deletions Ergo/Lang/Ast/Terms/Abstract/Dict.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,10 @@ public override bool Equals(ITerm other)
protected ITerm[] BuildKVPs()
{
var op = WellKnown.Operators.NamedArgument;
return Dictionary
return [.. Dictionary
.Select(kv => (ITerm)new Complex(op.CanonicalFunctor, kv.Key, kv.Value)
.AsOperator(op))
.OrderBy(o => o)
.ToArray();
.OrderBy(o => o)];
}

protected ITerm BuildCanonical()
Expand Down
2 changes: 1 addition & 1 deletion Ergo/Lang/Ast/Terms/Complex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public ITerm Substitute(Substitution s)
newArgs[i] = Arguments[i].Substitute(s);
}

var ret = WithArguments(newArgs.ToImmutableArray());
var ret = WithArguments([.. newArgs]);
return ret;
}

Expand Down
22 changes: 22 additions & 0 deletions Ergo/Lang/KnowledgeBase/KnowledgeBase.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Ergo.Interpreter;
using System.Collections;
using System.Collections.Specialized;
using System.Diagnostics;

namespace Ergo.Lang;

Expand All @@ -27,6 +28,27 @@ private KnowledgeBase(InterpreterScope scope, OrderedDictionary predicates, Depe
public int Count => Predicates.Values.Cast<List<Predicate>>().Sum(l => l.Count);
public void Clear() => Predicates.Clear();

/// <summary>
/// Removes all non-dynamic, non-cyclical predicates while preserving them in the dependency graph.
/// </summary>
public void Trim()
{
for (int k = Predicates.Count - 1; k >= 0; k--)
{
var list = (List<Predicate>)Predicates[k];
for (int i = list.Count - 1; i >= 0; i--)
{
var sig = DependencyGraph.GetKey(list[i]);
if (!DependencyGraph.GetNode(sig).TryGetValue(out var node))
Debug.Assert(false);
if (!node.IsCyclical && !list[i].IsDynamic)
list.RemoveAt(i);
}
if (list.Count == 0)
Predicates.RemoveAt(k);
}
}

public KnowledgeBase Clone()
{
var inner = new OrderedDictionary();
Expand Down
26 changes: 12 additions & 14 deletions Ergo/Lang/Lexer/Lexer.Symbols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,25 @@

public partial class ErgoLexer
{
public static readonly HashSet<string> TrueSymbols = new string[] {
public static readonly HashSet<string> TrueSymbols = [
"true", "⊤"
}.ToHashSet();
public static readonly HashSet<string> FalseSymbols = new string[] {
];
public static readonly HashSet<string> FalseSymbols = [
"false", "⊥"
}.ToHashSet();
public static readonly HashSet<string> CutSymbols = new string[] {
];
public static readonly HashSet<string> CutSymbols = [
"!"
}.ToHashSet();
];
public static readonly HashSet<string> BooleanSymbols =
FalseSymbols
.Concat(TrueSymbols)
.ToHashSet();
[.. FalseSymbols
, .. TrueSymbols];
public static readonly HashSet<string> KeywordSymbols =
CutSymbols
.Concat(BooleanSymbols)
.ToHashSet();
[.. CutSymbols
, .. BooleanSymbols];

public static readonly HashSet<string> PunctuationSymbols = new string[] {
public static readonly HashSet<string> PunctuationSymbols = [
"(", ")", "[", "]", "{", "}", ",", "."
}.ToHashSet();
];

public readonly string[] OperatorSymbols;

Expand Down
6 changes: 3 additions & 3 deletions Ergo/Lang/Parser/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ public Maybe<Complex> Complex()
}
return Atom()
.Map(functor => TupleParser.ParseArgList(this) // Regular tuples can't be 1 item long, but arg lists can.
.Select(args => new Complex(functor, args.Contents.ToArray())))
.Select(args => new Complex(functor, [.. args.Contents])))
.Or(() => MemoizeFailureAndFail<Complex>(scope.LexerState))
.Do(() => Probe.Leave(watch))
.Select(x => x.WithScope(scope))
Expand Down Expand Up @@ -684,7 +684,7 @@ public Maybe<ErgoProgram> Program()
return p.Exported();
return p;
});
return Maybe.Some(new ErgoProgram(directives.ToArray(), exportedPredicates.ToArray())
return Maybe.Some(new ErgoProgram([.. directives], exportedPredicates.ToArray())
.AsPartial(false))
.Do(() => Probe.Leave(watch))
;
Expand Down Expand Up @@ -746,7 +746,7 @@ public Maybe<ErgoProgram> ProgramDirectives()

if (!ret)
return default;
return Maybe.Some(new ErgoProgram(directives.ToArray(), Array.Empty<Predicate>())
return Maybe.Some(new ErgoProgram([.. directives], Array.Empty<Predicate>())
.AsPartial(true))
.Do(() => Probe.Leave(watch))
;
Expand Down
2 changes: 1 addition & 1 deletion XUnitTests/AdvancedSolverTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace Tests;


public class AdvancedSolverTests : ErgoTests
public class AdvancedSolverTests : ErgoTests<ErgoTestFixture>
{
public AdvancedSolverTests(ErgoTestFixture fixture) : base(fixture) { }
#region Rows
Expand Down
2 changes: 1 addition & 1 deletion XUnitTests/BasicSolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Tests;
using C = Complex;
using V = Variable;

public class BasicSolverTests : ErgoTests
public class BasicSolverTests : ErgoTests<ErgoTestFixture>
{
public BasicSolverTests(ErgoTestFixture fixture) : base(fixture) { }
#region Rows
Expand Down
13 changes: 4 additions & 9 deletions XUnitTests/CompilerTests.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@


using Ergo.Interpreter;
using Ergo.Lang.Ast;
using Ergo.Lang;
using Tests;
using Ergo.Lang.Extensions;
using Ergo.Runtime;

namespace Tests;

public class CompilerTests : ErgoTests
public class CompilerTests : ErgoTests<CompilerTestFixture>
{
public CompilerTests(ErgoTestFixture fixture) : base(fixture)
public CompilerTests(CompilerTestFixture fixture) : base(fixture)
{
var inlining = new Atom("inlining");
Interpreter.Load(ref InterpreterScope, inlining);
InterpreterScope = InterpreterScope.WithModule(InterpreterScope.EntryModule
.WithImport(inlining));
KnowledgeBase = InterpreterScope.BuildKnowledgeBase(CompilerFlags.Default); // Triggers Compiler library
}
[Theory]
[InlineData("inline_b", "inline_b.")] // instead of: inline_b :- inline_a.
Expand Down
2 changes: 1 addition & 1 deletion XUnitTests/IntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Tests;

public class IntegrationTests : ErgoTests
public class IntegrationTests : ErgoTests<ErgoTestFixture>
{
public IntegrationTests(ErgoTestFixture fixture) : base(fixture) { }
#region Rows
Expand Down
2 changes: 1 addition & 1 deletion XUnitTests/ParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class Operators
}
}

public class ParserTests : ErgoTests
public class ParserTests : ErgoTests<ErgoTestFixture>
{
public ParserTests(ErgoTestFixture test) : base(test) { }
[Theory]
Expand Down
2 changes: 1 addition & 1 deletion XUnitTests/TailCallOptimizationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Tests;


public class TailCallOptimizationTests : ErgoTests
public class TailCallOptimizationTests : ErgoTests<ErgoTestFixture>
{
const string Fib1000 =
"434665576869374564356885276750406258025646605173717804024817290895365554179490518904038798400792551692959" +
Expand Down
15 changes: 5 additions & 10 deletions XUnitTests/_Shared/ErgoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@

namespace Tests;

public class ErgoTests : IClassFixture<ErgoTestFixture>
public class ErgoTests<TFixture>(TFixture fixture) : IClassFixture<TFixture>
where TFixture : ErgoTestFixture
{
public readonly ErgoInterpreter Interpreter;
public InterpreterScope InterpreterScope;
public KnowledgeBase KnowledgeBase;
public readonly ErgoInterpreter Interpreter = fixture.Interpreter;
public InterpreterScope InterpreterScope = fixture.InterpreterScope;
public KnowledgeBase KnowledgeBase = fixture.KnowledgeBase;

public ErgoTests(ErgoTestFixture fixture)
{
Interpreter = fixture.Interpreter;
InterpreterScope = fixture.InterpreterScope;
KnowledgeBase = fixture.KnowledgeBase;
}
// "⊤" : "⊥"
protected void ShouldParse<T>(string query, T expected)
{
Expand Down
55 changes: 41 additions & 14 deletions XUnitTests/_Shared/SolverTestFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@

namespace Tests;

public class CompilerTestFixture : ErgoTestFixture
{
protected override string TestsModuleName => "inlining";
protected override CompilerFlags CompilerFlags => base.CompilerFlags
| CompilerFlags.EnableInlining;
protected override bool TrimKnowledgeBase => false;
}

public class ErgoTestFixture : IDisposable
{
public readonly ExceptionHandler NullExceptionHandler = default;
Expand All @@ -15,26 +23,45 @@ public class ErgoTestFixture : IDisposable
public readonly InterpreterScope InterpreterScope;
public readonly KnowledgeBase KnowledgeBase;

protected virtual string TestsModuleName => "tests";
protected virtual InterpreterFlags InterpreterFlags => InterpreterFlags.Default;
protected virtual CompilerFlags CompilerFlags => CompilerFlags.Default;
protected virtual bool TrimKnowledgeBase => true;

public ErgoTestFixture()
{
var basePath = Directory.GetCurrentDirectory();
var testsPath = Path.Combine(basePath, @"..\..\..\ergo");
var moduleName = new Atom("tests");

Interpreter = ErgoFacade.Standard
.BuildInterpreter(InterpreterFlags.Default);
var scope = Interpreter.CreateScope(x => x
.WithExceptionHandler(ThrowingExceptionHandler)
.WithoutSearchDirectories()
.WithSearchDirectory(testsPath)
);
scope = scope.WithRuntime(true);

Interpreter = CreateInterpreter();
InterpreterScope = CreateScope(testsPath);
LoadTestsModule(ref InterpreterScope);
KnowledgeBase = InterpreterScope.BuildKnowledgeBase(CompilerFlags);
if(TrimKnowledgeBase)
KnowledgeBase.Trim();
}

protected virtual ErgoInterpreter CreateInterpreter()
{
return ErgoFacade.Standard
.BuildInterpreter(InterpreterFlags);
}

protected virtual InterpreterScope CreateScope(string testsPath)
{
return Interpreter.CreateScope(x => x
.WithExceptionHandler(ThrowingExceptionHandler)
.WithoutSearchDirectories()
.WithSearchDirectory(testsPath))
.WithRuntime(true);
}

protected virtual void LoadTestsModule(ref InterpreterScope scope)
{
var module = Interpreter
.Load(ref scope, moduleName)
.Load(ref scope, new(TestsModuleName))
.GetOrThrow(new InvalidOperationException());
InterpreterScope = scope
.WithModule(scope.EntryModule.WithImport(module.Name));
KnowledgeBase = InterpreterScope.BuildKnowledgeBase(CompilerFlags.Default);
scope = scope.WithModule(scope.EntryModule.WithImport(module.Name));
}

~ErgoTestFixture()
Expand Down

0 comments on commit b899b42

Please sign in to comment.