Skip to content

Commit 7f10fe0

Browse files
Update
1 parent c593603 commit 7f10fe0

1 file changed

Lines changed: 117 additions & 14 deletions

File tree

roadmap/laplace-pspice-feasibility.md

Lines changed: 117 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,15 @@ Where `H(s)` is a finite rational polynomial in `s` whose coefficients reduce to
4040
8. [Reader Integration](#reader-integration)
4141
9. [Diagnostics](#diagnostics)
4242
10. [Compatibility Policy](#compatibility-policy)
43-
11. [Implementation Plan](#implementation-plan)
44-
12. [Acceptance Criteria](#acceptance-criteria)
45-
13. [Test Plan](#test-plan)
46-
14. [Worked Examples](#worked-examples)
47-
15. [Sample Netlists](#sample-netlists)
48-
16. [Debugging Guide](#debugging-guide)
49-
17. [Key Files](#key-files)
50-
18. [References](#references)
43+
11. [Multiple Syntax Strategy](#multiple-syntax-strategy)
44+
12. [Implementation Plan](#implementation-plan)
45+
13. [Acceptance Criteria](#acceptance-criteria)
46+
14. [Test Plan](#test-plan)
47+
15. [Worked Examples](#worked-examples)
48+
16. [Sample Netlists](#sample-netlists)
49+
17. [Debugging Guide](#debugging-guide)
50+
18. [Key Files](#key-files)
51+
19. [References](#references)
5152

5253
---
5354

@@ -154,6 +155,8 @@ Input-expression subset:
154155
- `F` and `H` current-controlled Laplace sources.
155156
- `B` source Laplace forms.
156157
- Arbitrary input expressions such as `V(a)-V(b)+I(Vsense)`.
158+
- Alternative `E` / `G` Laplace syntax variants that omit `=` or put `=` directly after `LAPLACE`.
159+
- `VALUE={LAPLACE(...)}` / function-like ABM forms.
157160
- Non-rational transfer expressions.
158161
- Explicit delay syntax such as `TD=` or `DELAY=`.
159162
- Initial-condition syntax for Laplace internal state.
@@ -492,6 +495,8 @@ laplace transfer coefficients must be constant expressions
492495
laplace transfer expression reserves symbol 's'; use a different parameter name
493496
laplace delay syntax is not supported yet
494497
laplace multiplier M is not supported yet
498+
laplace syntax variant is recognized but not supported yet
499+
laplace function-like VALUE form is not supported yet; use E/G LAPLACE {V(...)} = {H(s)}
495500
laplace source supports only E and G voltage-controlled forms in this version
496501
```
497502

@@ -512,8 +517,11 @@ Good diagnostics are part of compatibility. A precise rejection is better than f
512517
| `E ... LAPLACE {V(n1,n2)} = {H(s)}` | Support | Keep |
513518
| `G ... LAPLACE {V(n)} = {H(s)}` | Support | Keep |
514519
| `G ... LAPLACE {V(n1,n2)} = {H(s)}` | Support | Keep |
520+
| `E` / `G ... LAPLACE {V(n)} {H(s)}` | Targeted unsupported diagnostic until canonical form is stable | Add recognizer that lowers to the same model |
521+
| `E` / `G ... LAPLACE = {V(n)} {H(s)}` | Targeted unsupported diagnostic until canonical form is stable | Add recognizer that lowers to the same model |
515522
| `F` / `H` current-controlled forms | Targeted unsupported diagnostic | Map to built-in current-controlled Laplace entities |
516523
| `B` source Laplace forms | Targeted unsupported diagnostic | Investigate PSpice ABM syntax |
524+
| `VALUE={LAPLACE(...)}` function-like form | Targeted unsupported diagnostic | Investigate as source-level special form |
517525
| Arbitrary input expression | Reject | Lower through helper behavioral source or custom behavior |
518526
| Rational polynomial in `s` | Support | Keep |
519527
| Non-rational functions of `s` | Reject | Likely keep rejected |
@@ -533,6 +541,71 @@ E1 out 0 LAPLACE = {V(in)} {1/(1+s*tau)}
533541
E1 out 0 VALUE = {LAPLACE(V(in), 1/(1+s*tau))}
534542
```
535543

544+
## Multiple Syntax Strategy
545+
546+
Treat multiple PSpice spellings as a compatibility layer over one internal model. The runtime and coefficient builder should not care which syntax variant was used.
547+
548+
All supported forms should normalize into the same `LaplaceSourceDefinition`:
549+
550+
```csharp
551+
internal sealed class LaplaceSourceDefinition
552+
{
553+
public string SourceName { get; }
554+
public string SourceKind { get; }
555+
public LaplaceSourceInput Input { get; }
556+
public string InputExpression { get; }
557+
public string TransferExpression { get; }
558+
public LaplaceTransferFunction TransferFunction { get; }
559+
public double Delay { get; }
560+
public SpiceLineInfo LineInfo { get; }
561+
}
562+
```
563+
564+
Use small syntax recognizers rather than one large parser branch:
565+
566+
```csharp
567+
internal interface ILaplaceSyntaxRecognizer
568+
{
569+
bool TryParse(
570+
string sourceName,
571+
string sourceKind,
572+
ParameterCollection parameters,
573+
IReadingContext context,
574+
out LaplaceSourceDefinition definition);
575+
}
576+
```
577+
578+
Recognizer priority should be explicit and tested:
579+
580+
1. `CanonicalExpressionAssignmentRecognizer` for `LAPLACE {V(in)} = {H(s)}`.
581+
2. `NoEqualsExpressionPairRecognizer` for `LAPLACE {V(in)} {H(s)}`.
582+
3. `EqualsExpressionPairRecognizer` for `LAPLACE = {V(in)} {H(s)}`.
583+
4. `CurrentControlledRecognizer` for later `F` / `H` forms using `I(Vsense)`.
584+
5. `ValueLaplaceFunctionRecognizer` for later `VALUE={LAPLACE(...)}` and `B`-source ABM forms.
585+
6. `UnsupportedKnownVariantRecognizer` for recognized-but-deferred forms.
586+
587+
The last recognizer is deliberate. If a user writes a known PSpice Laplace variant that is not implemented yet, emit a targeted diagnostic instead of letting the line fall through to `VALUE`, `TABLE`, or generic parameter-count handling.
588+
589+
### Syntax Families
590+
591+
| Family | Example | Near-term behavior | Notes |
592+
|--------|---------|--------------------|-------|
593+
| Canonical assignment | `E1 out 0 LAPLACE {V(in)} = {1/(1+s*tau)}` | Support first | Exercises grammar gap and runtime mapping. |
594+
| No-equals expression pair | `E1 out 0 LAPLACE {V(in)} {1/(1+s*tau)}` | Add after canonical | Should normalize to the same definition and coefficients. |
595+
| Equals-after-keyword pair | `E1 out 0 LAPLACE = {V(in)} {1/(1+s*tau)}` | Add after canonical | Likely parses differently; keep syntax handling isolated in a recognizer. |
596+
| Current-controlled | `F1 out 0 LAPLACE {I(Vsense)} = {H(s)}` | Later milestone | Runtime entities exist, but controlling-source parsing and PSpice compatibility need tests. |
597+
| Function-like `VALUE` | `E1 out 0 VALUE = {LAPLACE(V(in), H(s))}` | Investigate later | Must be handled as source-level Laplace, not a scalar expression function. |
598+
| `B` source ABM | `B1 out 0 V = {LAPLACE(V(in), H(s))}` | Investigate later | May require arbitrary input-expression lowering or custom behavior. |
599+
| Delay/options | `TD=...`, `DELAY=...` | Reject initially | Runtime has `Delay`; PSpice syntax and semantics need confirmation. |
600+
601+
### Normalization Rules
602+
603+
- Equivalent `E` / `G` syntax variants must produce identical input nodes, transfer coefficients, delay, and entity type.
604+
- Syntax recognizers should only parse surface shape. They should call the same input parser and transfer-expression builder.
605+
- The canonical recognizer is the only recognizer needed for the MVP.
606+
- Later recognizers should be added one at a time with compatibility matrix tests.
607+
- Function-like forms must not be registered in the normal scalar function table. They are analysis-dependent source constructs.
608+
536609
## Implementation Plan
537610

538611
### Phase 0: Runtime Spike
@@ -571,11 +644,12 @@ If manual entity construction fails, stop and investigate the dependency before
571644
### Phase 3: `E` Source Mapping
572645

573646
1. Add `LaplaceSourceParser` and source definition models.
574-
2. Detect `LAPLACE` in `VoltageSourceGenerator.CreateCustomVoltageSource(...)`.
575-
3. Parse `V(node)` / `V(node1,node2)` input.
576-
4. Map to `LaplaceVoltageControlledVoltageSource`.
577-
5. Add OP and AC integration tests.
578-
6. Add malformed syntax and unsupported-feature diagnostics.
647+
2. Add `CanonicalExpressionAssignmentRecognizer` as the first syntax recognizer.
648+
3. Detect `LAPLACE` in `VoltageSourceGenerator.CreateCustomVoltageSource(...)`.
649+
4. Parse `V(node)` / `V(node1,node2)` input.
650+
5. Map to `LaplaceVoltageControlledVoltageSource`.
651+
6. Add OP and AC integration tests.
652+
7. Add malformed syntax and unsupported-feature diagnostics.
579653

580654
### Phase 4: `G` Source Mapping
581655

@@ -584,7 +658,16 @@ If manual entity construction fails, stop and investigate the dependency before
584658
3. Map to `LaplaceVoltageControlledCurrentSource`.
585659
4. Add sign-convention and load-resistor tests.
586660

587-
### Phase 5: Polish
661+
### Phase 5: Syntax Compatibility Layer
662+
663+
1. Add `UnsupportedKnownVariantRecognizer` so common deferred forms receive targeted diagnostics.
664+
2. Add `NoEqualsExpressionPairRecognizer` for `LAPLACE {input} {transfer}` only after canonical tests pass.
665+
3. Add `EqualsExpressionPairRecognizer` for `LAPLACE = {input} {transfer}` only after no-equals tests pass.
666+
4. Verify supported variants normalize to identical `LaplaceSourceDefinition` values.
667+
5. Keep function-like `VALUE={LAPLACE(...)}` forms diagnostic-only until their PSpice semantics are confirmed.
668+
6. Keep `F` / `H` recognizers diagnostic-only until current-controlled tests are planned.
669+
670+
### Phase 6: Polish
588671

589672
1. Decide and document transient support based on step-response results.
590673
2. Add generated C# writer support if parity is required for the release.
@@ -598,8 +681,10 @@ The MVP is ready when all of these are true:
598681
- `E` and `G` Laplace sources parse without disturbing existing `VALUE`, `POLY`, or `TABLE` behavior.
599682
- Transfer coefficients are generated in ascending powers of `s`.
600683
- Parameterized low-pass, high-pass, and biquad examples produce expected coefficients.
684+
- Any supported alternate PSpice syntax variants normalize to the same definitions and coefficients as the canonical form.
601685
- AC integration tests match expected magnitude and phase at key frequencies.
602686
- Unsupported syntax produces targeted validation errors with line info.
687+
- Recognized-but-deferred PSpice variants produce targeted diagnostics rather than falling through to unrelated source handling.
603688
- No supported user mistake falls through to a generic parser exception.
604689
- Transient support is either verified by tests or explicitly documented as not yet claimed.
605690
- User documentation states syntax, supported analyses, limitations, and examples.
@@ -647,6 +732,22 @@ Place near [src/SpiceSharpParser.Tests/Parsers](../src/SpiceSharpParser.Tests/Pa
647732
- Unsupported arbitrary input expression.
648733
- Unsupported delay and `M=` parameters.
649734

735+
### Compatibility Matrix Tests
736+
737+
For every supported syntax variant, verify:
738+
739+
- It maps to the same `LaplaceSourceDefinition` as the canonical form.
740+
- It produces the same numerator and denominator arrays.
741+
- It creates the same SpiceSharpBehavioral entity type.
742+
- It uses the same output and control-node ordering.
743+
- It keeps existing `VALUE`, `POLY`, and `TABLE` behavior unchanged.
744+
745+
For every recognized but deferred syntax variant, verify:
746+
747+
- It reports a targeted validation error.
748+
- It does not fall through to unrelated source generation.
749+
- It includes source name and line information.
750+
650751
### Integration Tests
651752

652753
Place beside existing analog behavioral tests under [src/SpiceSharpParser.IntegrationTests/AnalogBehavioralModeling](../src/SpiceSharpParser.IntegrationTests/AnalogBehavioralModeling).
@@ -921,6 +1022,8 @@ When a Laplace test fails, narrow the problem by layer.
9211022
### Source Reader
9221023

9231024
- Is `LAPLACE` a `WordParameter`?
1025+
- Which `ILaplaceSyntaxRecognizer` matched?
1026+
- Did a recognized-but-deferred syntax go through `UnsupportedKnownVariantRecognizer`?
9241027
- Is the next parameter an `ExpressionAssignmentParameter`?
9251028
- Did source type normalize to `e` or `g`?
9261029
- Did input parsing produce exactly two control nodes?

0 commit comments

Comments
 (0)