|
| 1 | +'use strict'; |
| 2 | +import { Info, SetFamily, BoolSetFamily, DagSetFamily, ProdSetFamily } from "./setFamily.js"; |
| 3 | +import { filterByConstraint, combineInputs, Ostream, CpigInput, outputPath } from "./main.js"; |
| 4 | +import { Edge, Graph } from "./graph.js"; |
| 5 | + |
| 6 | +declare class Param { |
| 7 | + constructor(name: string, widget: any, label?: string, description?: string); |
| 8 | +} |
| 9 | +declare class ParamGroup { |
| 10 | + constructor(name: string, paramList: Param[], converter?: any, description?: string); |
| 11 | +} |
| 12 | +declare var CheckBoxWidget: any; |
| 13 | +declare var SelectWidget: any; |
| 14 | +declare var SelectOption: any; |
| 15 | +declare function createForm(wrapperId: string, paramGroup: ParamGroup, |
| 16 | + func: (input: string, stdout: Ostream) => any, clearOutput?: boolean): any; |
| 17 | + |
| 18 | +export async function setup(sfUrl: string, inputUrls: string[]) { |
| 19 | + const {sf, input} = await fetchInput(sfUrl, inputUrls); |
| 20 | + const params: Param[] = []; |
| 21 | + addSfParams(params, sf); |
| 22 | + addPredParams(params, input.predicates!); |
| 23 | + const paramGroup = new ParamGroup('myForm', params); |
| 24 | + createForm('myApp', paramGroup, function (f2fInput, stdout) { |
| 25 | + cli(sf, input, f2fInput, stdout); |
| 26 | + }); |
| 27 | +} |
| 28 | + |
| 29 | +export async function fetchInput(sfUrl: string, inputUrls: string[]) { |
| 30 | + const pageLoadPromise = new Promise(function(resolve, reject) { |
| 31 | + window.addEventListener('DomContentLoaded', resolve); |
| 32 | + }); |
| 33 | + const sfPromise = window.fetch(sfUrl) |
| 34 | + .then(response => response.json()) |
| 35 | + .then(json => SetFamily.fromJson(json)); |
| 36 | + const inputsPromise = Promise.all(inputUrls.map( |
| 37 | + inputUrl => window.fetch(inputUrl).then(response => response.json()))); |
| 38 | + const sf = await sfPromise; |
| 39 | + const input = combineInputs(await inputsPromise); |
| 40 | + console.log(sf); |
| 41 | + console.log(input); |
| 42 | + return {sf: sf, input: input}; |
| 43 | +} |
| 44 | + |
| 45 | +function addSfParams(output: Param[], setFamily: SetFamily) { |
| 46 | + const name = setFamily.info.name; |
| 47 | + if(setFamily instanceof BoolSetFamily) { |
| 48 | + output.push(new Param(name, new CheckBoxWidget())); |
| 49 | + } |
| 50 | + else if(setFamily instanceof DagSetFamily) { |
| 51 | + output.push(new Param(name, new SelectWidget(setFamily.values.map( |
| 52 | + vInfo => new SelectOption(vInfo.name, vInfo.name, vInfo.label || vInfo.name)), setFamily.defVal))); |
| 53 | + } |
| 54 | + else if(setFamily instanceof ProdSetFamily) { |
| 55 | + for(const part of setFamily.parts) { |
| 56 | + addSfParams(output, part); |
| 57 | + } |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +function addPredParams(output: Param[], preds: Info[]) { |
| 62 | + for(const pred of preds) { |
| 63 | + output.push(new Param('pred.' + pred.name, new CheckBoxWidget(), pred.name)); |
| 64 | + } |
| 65 | +} |
| 66 | + |
| 67 | +function cli(sf: SetFamily, input: CpigInput, f2fInput: any, stdout: Ostream) { |
| 68 | + const chosenPreds = []; |
| 69 | + for(const pred of input.predicates!) { |
| 70 | + if(f2fInput['pred.'+pred.name]) { |
| 71 | + chosenPreds.push(pred.name); |
| 72 | + } |
| 73 | + } |
| 74 | + const procInput = filterByConstraint([input], f2fInput, sf); |
| 75 | + |
| 76 | + if(chosenPreds.length === 2) { |
| 77 | + const [u, v] = chosenPreds; |
| 78 | + outputPath(procInput.impG, u, v, stdout); |
| 79 | + outputPath(procInput.impG, v, u, stdout); |
| 80 | + } |
| 81 | + const {scc, dag} = procInput.impG.trCompression(chosenPreds.length > 0 ? chosenPreds : undefined); |
| 82 | + const redDag = dag.trRed(); |
| 83 | + const s = sccDagToStr(scc, redDag); |
| 84 | + stdout.log(s); |
| 85 | +} |
| 86 | + |
| 87 | +function componentStr(S: string[], parens: boolean) { |
| 88 | + const begDelim = parens ? '( ' : ''; |
| 89 | + const endDelim = parens ? ' )' : ''; |
| 90 | + return S.length === 1 ? S[0] : begDelim + S.join(' = ') + endDelim; |
| 91 | +} |
| 92 | + |
| 93 | +function sccDagToStr(scc: Map<string, string[]>, dag: Graph<string, Edge<string>>) { |
| 94 | + const lines = []; |
| 95 | + for(const edge of dag.edges) { |
| 96 | + const uS = scc.get(edge.from)!, vS = scc.get(edge.to)!; |
| 97 | + lines.push(componentStr(uS, true) + ' ==> ' + componentStr(vS, true)); |
| 98 | + } |
| 99 | + return lines.join('\n'); |
| 100 | +} |
0 commit comments